kubernetes ingress service annotations - kubernetes

I am setting up an ingress service following some k8s documentation, but I am not able to understand the following annotations:
kubernetes.ip/ingress.class:
nginx.ingress.kubernetes.io/rewrite-target:
Do you know what these annotations do?
Thanks in advance.

kubernetes.io/ingress.class annotation is officially deprecated:
Before the IngressClass resource was added in Kubernetes 1.18, a
similar concept of Ingress class was often specified with a
kubernetes.io/ingress.class annotation on the Ingress. Although this
annotation was never formally defined, it was widely supported by
Ingress controllers, and should now be considered formally deprecated.
Instead you should use the ingressClassName:
The newer ingressClassName field on Ingresses is a replacement for
that annotation, but is not a direct equivalent. While the annotation
was generally used to reference the name of the Ingress controller
that should implement the Ingress, the field is a reference to an
IngressClass resource that contains additional Ingress
configuration, including the name of the Ingress controller.
The rewrite annotation does as follows:
In some scenarios the exposed URL in the backend service differs from
the specified path in the Ingress rule. Without a rewrite any request
will return 404. Set the annotation
nginx.ingress.kubernetes.io/rewrite-target to the path expected by
the service.
If the Application Root is exposed in a different path and needs to be
redirected, set the annotation nginx.ingress.kubernetes.io/app-root
to redirect requests for /.
For a more detailed example I strongly suggest you can check out this source. It shows exactly how rewriting works.

Since Kubernetes 1.18+, kubernetes.io/ingress.class annotation is deprecated.
You have to create an IngressClass like:
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: alb-ingress-class
spec:
controller: ingress.k8s.aws/alb
And then reference it in your Ingress declaration:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: ...
name: my-fabulous-ingress
annotations:
...
labels:
...
spec:
ingressClassName: "alb-ingress-class"
rules:
...
Important: Be sure to create the IngressClass before the Ingress (because it is referenced by the Ingress)
Note: If in the same manifest, putting the IngressClass block above the Ingress one is enough.
More info:
https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/
https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/ingress/ingress_class/

Related

How to set max_conn for nginx ingress?

I have Nginx Ingress Controller which is deployed via official Helm chart, in the doc I saw that I can set max_conn parameter, but I didn't get how to set it. I want to set it to 2, so that maximum of 2 clients could connect to my services. How do I set it? Should I set it in ingress controller values during helm install of Ingress Controller or in Ingress manifest?
From this document you can add these in the annotations
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: web-ingress
namespace: default
annotations:
nginx.org/max-conns: 2
Try this and let me know if this works
Found a similar stack question with a different approach which can help you to resolve your issues.

Kubernetes ingress "kubernetes.io/ingress.class" vs "ingressClassName"

My Kubernetes ingress has the following:
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: alb
...
...
# -- Defines which ingress controller will implement the resource
ingressClassName: ""
I'm a bit confused about the difference between "kubernetes.io/ingress.class" and "ingressClassName.".
I believe "kubernetes.io/ingress.class" needs to match the ingressClass as defined in the AWS ALB Ingress Controller.
However, then I'm confused about the role of "ingressClassName"? As that seems to be the same thing.
Any clarity would be appreciated.
Actually, both refer to the same thing, but kubernetes.io/ingress.class is deprecated from Kubernetes v1.22+. and ingressClassName is introduced in 1.18, so if you are using higher version you can ingressClassName
Before the IngressClass resource and ingressClassName field were added in Kubernetes 1.18, Ingress classes were specified with a kubernetes.io/ingress.class annotation on the Ingress. This annotation was never formally defined, but was widely supported by Ingress controllers.
The newer ingressClassName field on Ingresses is a replacement for that annotation, but is not a direct equivalent. While the annotation was generally used to reference the name of the Ingress controller that should implement the Ingress, the field is a reference to an IngressClass resource that contains additional Ingress configuration,
ingress-deprecated-annotation
Your example is
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: alb
its equivalent value is className: "nginx"
ingress:
enabled: true
className: "alb" -> ingressClassName
if you check the ingress template, it will be like this
ingressClassName: {{ .Values.ingress.className }}

How to set requests per second limit on GKE and Kong Ingress?

I have a cluster on GKE and I want to set a limit for incoming requests, but I cannot find a way to do it using Kong Ingress Controller. I can't find any documentation or info about this specific topic.
Following the steps in this article, I achieved the desired results by adding the rate limit plugin in my kongo ingress. To do so, first, update / create your ingress definition and add the annotations defined below:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: func
namespace: default
annotations:
kubernetes.io/ingress.class: kong # <-- THIS
plugins.konghq.com: http-ratelimit # <-- THIS
spec:
...
After, to finally set the rate-limit, use this definition and apply it in your kubernetes cluster:
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: http-ratelimit
namespace: default
config:
policy: local
second: 1
plugin: rate-limiting
This will create a restriction of 1 request per second in your ingress. If you want anything different, just change the config section with your own configuration. Check the plugin's documentation for all possible configurations.

Ingress in Kubernetes

I was doing some research about ingress and it seems I have to create a new ingress resource for each namespace. Is that correct?
I just created 2 separate ingress resources in different namespaces in my GKE cluster but it seems to use the same LB in(which is great for cost) but I would think it is possible to have clashes then. (when using same path). I just tried it and the first one I've created is still working on the path, the other newer one on the same path is just not working.
Can someone explain me the correct setup for ingress?
As Kubernetes works, ingress controller won't pass a packet to a service that is in a different namespace from the ingress resource. So, if you create an ingress resource in the default namespace, all your services must be in the default namespace as well.
This is something that won't change. EVER. There has been a feature request years ago, and kubernetes team announced that it's not going to happen. It introduces a security hole when ingress controller is being able to transpass a namespace.
Now, what we do in these situations is actually pretty neat. You will have to do the following:
Say you have 2 services in the namespaces you need. e.g. service1.foo and service2.bar.
create 2 headless services without selectors and 2 Endpoint objects pointing to the IP addresses of the services service1.foo and service2.bar, in the same namespace as the ingress resource. The headless service without selectors will force kube-dns (or coreDNS) to search for either ExternalName type service or an Endpoint object. Now, the only requirement here is that your headless service and the Endpoint object must have the same name.
Create your ingress resource pointing to the headless services.
It should look like this (for 1 service):
Say the IP address of service1.foo is 10.10.10.10. Your headless service and the Endpoint object would be:
apiVersion: v1
kind: Service
metadata:
name: bait-svc
spec:
clusterIP: None
ports:
- name: http
port: 80
targetPort: 80
---
apiVersion: v1
kind: Endpoints
metadata:
name: bait-svc
subsets:
- addresses:
- ip: 10.10.10.10
ports:
- port: 80
protocol: TCP
and Ingress resource:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
tls:
- secretName: ssl-certs
rules:
- host: site1.training.com
http:
paths:
- path: /
backend:
serviceName: bait-svc
servicePort: 80
So, the Ingress points to the bait-svc, and bait-svc points to service1.foo. And you will do this for each service.
UPDATE
I am thinking now, it might not work with GKE Ingress Controller, as on GKE you need a NodePort type service for the HTTP load balancer to reach the service. As you can see, in my example I've got nginx Ingress Controller.
Independently if it works or not, I would recommend using some other Ingress Controller. It's not that GKE IC is not good. It is quite robust, but almost always you end up hitting some limitation. Other ICs are more flexible.
The behavior of conflicting Ingress routes is undefined and implementation dependent. In most cases it’s just last writer wins.

Confusing Kubernetes semantics in NetworkPolicy yaml spec

Observe: the field value of ingress under spec.
Case 1: DENY all traffic to an application. Here ingress takes an empty array as its value.
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-deny-all
spec:
podSelector:
matchLabels:
app: web
ingress: [] # <-- This DENIES ALL traffic
Case 2: ALLOW all traffic to an application. Here ingress takes a list item of empty map as its value.
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-allow-all
namespace: default
spec:
podSelector:
matchLabels:
app: web
ingress:
- {} # <-- This ALLOWS ALL traffic
I'm just wondering that if I were to read out loud the assignment values of ingress of the above how do I read it?
YAML has a couple of different ways to write lists (and for that matter most other objects). This might become clearer if we write both using the same list syntax:
# deny-all
ingress: []
# allow-all
ingress: [{}]
Assume that one of these policies is the only one that matches the pod in question. The first policy has no items in the ingress list, the second one. The NetworkPolicySpec API documentation tells us
Traffic is allowed to a pod [...] if the traffic matches at least one ingress rule across all of the NetworkPolicy objects whose podSelector matches the pod.
So in the first case, the policy matches the pod, but there are no ingress rules, and therefore there isn't at least one ingress rule that matches, so traffic is denied.
In the second case there is a single rule, which is an empty NetworkPolicyIngressRule. That has two fields, from and ports, but the documentation for both of those fields says
If this field is empty or missing, this rule matches all [sources or ports]
So the empty-object rule matches all sources and all ports; and since there is a matching ingress rule, traffic is allowed.