Use Nginx Ingress sequentially in Kubernetes to expose service - nginx

I have three namespaces in my GKE cluster: nginx-global, nginx-a, app-a.
kubectl create namespace nginx-global
kubectl label namespace nginx-global namespace-type=nginx-global
kubectl create namespace nginx-a
kubectl label namespace nginx-a project=a
kubectl label namespace nginx-a namespace-type=nginx
kubectl create namespace app-a
kubectl label namespace app-a project=a
kubectl label namespace app-a namespace-type=apps
Now I installed two nginx ingress controllers in the namespaces nginx-global and nginx-a:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx ingress-nginx/ingress-nginx --namespace nginx-global --set controller.scope.namespaceSelector="namespace-type=nginx"
helm install ingress-nginx-a ingress-nginx/ingress-nginx --namespace nginx-a --set controller.scope.namespaceSelector="namespace-type=apps,project=a" --set controller.service.type="ClusterIP" --set controller.ingressClassResource.name="nginx-a"
And I create a dummy app in the last namespace app-a:
apiVersion: v1
kind: Service
metadata:
name: echo1
namespace: app-a
spec:
ports:
- port: 80
targetPort: 5678
selector:
app: echo1
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo1
namespace: app-a
spec:
selector:
matchLabels:
app: echo1
replicas: 2
template:
metadata:
labels:
app: echo1
spec:
containers:
- name: echo1
image: hashicorp/http-echo
args:
- "-text=echo1"
ports:
- containerPort: 5678
Now, it is my aim to expose the dummy app via the ingress-nginx LoadBalancer by going through the ingress-nginx-a ClusterIP in the middle.
For this I was first creating an A record at Cloudflare *.example.com pointing to the LoadBalancer IP. Then I used the following Ingress rules:
# For pointing from the first nginx ingress (ingress-nginx) to the second nginx ingress (ingress-nginx-a)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx2-ingress
namespace: nginx-a
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- host: "*.example.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: ingress-nginx-a-controller
port:
number: 80
#For pointing from the second nginx ingress (ingress-nginx-a) to the echo service
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echo-ingress
namespace: app-a
annotations:
kubernetes.io/ingress.class: "nginx-a"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- host: "test.example.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: echo1
port:
number: 80
However, I simply get the usual "404 Not Found" nginx error. Do you know what I did wrong?

Nginx ingress might create cluster role bindings with same name in all installations. Check
kubectl get clusterrolebindings | grep ingress
So if one of them is colliding with the other this might cause other one to be disfunctional. This is also true for other cluster wide resources

Related

Ingress in GKE does not do the routing identically despite same IP at DNS level

I have setup in my GKE cluster an nginx ingress as follows:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx --namespace nginx-ingress
A load balancer with its IP came up.
Now I added two DNS pointing to that domain at Cloudflare:
In addition I created a namespace app-a
kubectl create namespace app-a
kubectl label namespace app-a project=a
and deployed an app there:
apiVersion: v1
kind: Service
metadata:
name: echo1
namespace: app-a
spec:
ports:
- port: 80
targetPort: 5678
selector:
app: echo1
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo1
namespace: app-a
spec:
selector:
matchLabels:
app: echo1
replicas: 2
template:
metadata:
labels:
app: echo1
spec:
containers:
- name: echo1
image: hashicorp/http-echo
args:
- "-text=echo1"
ports:
- containerPort: 5678
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echo-ingress-global
namespace: app-a
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- host: "test.my-domain.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: echo1
port:
number: 80
Things look good in Lens, so I thought to test it out.
When I was entering eu1.my-domain.com, I get
which is intended, of course.
but when I entered test.my-domain.com, I get that the website is unreachable: DNS_PROBE_FINISHED_NXDOMAIN, although I expected to see the dummy output of the dummy app.
Even more strangely, no matter if I get the well-responding result or the non-responding one, in the logs of the nginx controller there is nothing showing up for any of the calls.
Can you help me, such that I can access the test.my-domain.com homepage?

Kubernetes nginx ingress cannot find backend service

I have deployed my API to Kubernetes on AKS through kubectl command from my local machine. But the nginx ingress is not able to resolve the backend endpoint. The ingress logs has an error The service 'hello-world/filter-api' does not have any active endpoint
Steps followed:
Install dapr on AKS
dapr init -k --set global.tag=1.1.2
Install nginx ingress on AKS
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx -f ...\dapr\components\dapr-annotations.yaml --set image.tag=1.11.1 -n ingress-nginx
Apply manifest
kubectl apply -f .\services\filter.yaml
What did I try?
Verified the selectors and labels
Followed the steps mentioned Troublshooting nginx ingress
I tried to deploy this to local Kubernetes cluster on windows with docker desktop. This works fine. What am I missing?
filter.yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: filter-cm
namespace: hello-world
labels:
app: hello-world
service: filter
data:
ASPNETCORE_ENVIRONMENT: Development
ASPNETCORE_URLS: http://0.0.0.0:80
PATH_BASE: /filter
PORT: "80"
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: filter
namespace: hello-world
labels:
app: hello-world
service: filter
spec:
replicas: 1
selector:
matchLabels:
service: filter
template:
metadata:
labels:
app: hello-world
service: filter
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "filter-api"
dapr.io/app-port: "80"
dapr.io/config: "dapr-config"
spec:
containers:
- name: filter-api
image: client/hello-world-filter-api:0.0.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
protocol: TCP
envFrom:
- configMapRef:
name: filter-cm
imagePullSecrets:
- name: regcred
---
apiVersion: v1
kind: Service
metadata:
name: filter-api
namespace: hello-world
labels:
app: hello-world
service: filter
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30001
protocol: TCP
name: http
selector:
service: filter
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: filter-ingress
namespace: hello-world
labels:
app: hello-world
service: filter
spec:
rules:
- http:
paths:
- path: /filter
pathType: Prefix
backend:
service:
name: filter-api
port:
number: 80
In the service selector, use matchLabels for the service to find the backend pods
example:
selector:
matchLabels:
service: filter

502 Bad Gateway with Kubernetes Ingress Digital Ocean

I have a kubernetes setup with the configuration like below:
I am using this mandatory file:
https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.26.1/deploy/static/mandatory.yaml
https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.26.1/deploy/static/provider/cloud-generic.yaml
My ingress:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: api-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- api.service.com
secretName: api-tls
rules:
- host: api.service.com
http:
paths:
- backend:
serviceName: api-service
servicePort: 80
My service:
#########################################################
# Service for API Gateway service
#########################################################
apiVersion: v1
kind: Service
metadata:
name: api-service
labels:
name: api
spec:
selector:
app: api
ports:
- name: http
port: 80
targetPort: 3000
nodePort: 30000
protocol: TCP
- name: https
port: 443
targetPort: 3000
nodePort: 30001
protocol: TCP
type: NodePort
sessionAffinity: ClientIP
My deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
name: api
name: api
spec:
replicas: 1
selector:
matchLabels:
name: api
template:
metadata:
labels:
name: api
app: api
spec:
containers:
- env:
- name: CACHER
value: redis://redis:6379
- name: LOGLEVEL
value: info
- name: NAMESPACE
value: myName
- name: PORT
value: "3000"
- name: SERVICEDIR
value: services
- name: SERVICES
value: api
- name: TRANSPORTER
value: nats://nats:4222
ports:
- containerPort: 3000
image: registry.digitalocean.com/my-registry/my-image:latest
imagePullPolicy: ""
name: api
resources: {}
imagePullSecrets:
- name: my-registry
restartPolicy: Always
serviceAccountName: ""
volumes: null
status: {}
If I use Service NodePort with port 30001 and its own IP, I don't have any problem, but with LoadBalancer always throws a 502 Bad gateway.
Any idea?
Thanks!
Please, avoid using these files manually. This file seems outdated too. Use helm if you don't like surprises. Because these are managed services.
First, install Helm on your laptop. Then log in to your Digitalocean in the command panel. Delete existing Nginx ingress implementations. Then run these commands one by one.
At first add the ingress controller to the default namespace
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
Then update the helm repo
helm repo update
Then finally run this command
helm install nginx-ingress ingress-nginx/ingress-nginx --set controller.publishService.enabled=true
To check the installation run this command
kubectl --namespace default get services -o wide -w nginx-ingress-ingress-nginx-controller
There is also a digital ocean recommended approach. You can use Digital Ocean Marketplace to install Nginx-Ingress too. Digitalocean will then automatically run these aforementioned commands for you! If you check their Github account, you will find that they are also using helm for their marketplace services. It's time to adopt Helm.

Session affinity cookie not working anymore (Kubernetes with Nginx ingress)

An upgrade of our Azure AKS - Kubernetes environment to Kubernetes version 1.19.3 forced me to also upgrade my Nginx helm.sh/chart to nginx-ingress-0.7.1. As a result I was forced to change the API version definition to networking.k8s.io/v1 since my DevOps pipeline failed accordingly (a warning for old API resulting in an error). However, now I have the problem that my session affinity annotation is ignored and no session cookies are set in the response.
I am desperately changing names, trying different unrelated blog posts to somehow fix the issue.
Any help would be really appreciated.
My current nginx yaml (I have removed status/managed fields tags to enhance readability):
kind: Deployment
apiVersion: apps/v1
metadata:
name: nginx-ingress-infra-nginx-ingress
namespace: ingress-infra
labels:
app.kubernetes.io/instance: nginx-ingress-infra
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: nginx-ingress-infra-nginx-ingress
helm.sh/chart: nginx-ingress-0.7.1
annotations:
deployment.kubernetes.io/revision: '1'
meta.helm.sh/release-name: nginx-ingress-infra
meta.helm.sh/release-namespace: ingress-infra
spec:
replicas: 2
selector:
matchLabels:
app: nginx-ingress-infra-nginx-ingress
template:
metadata:
creationTimestamp: null
labels:
app: nginx-ingress-infra-nginx-ingress
annotations:
prometheus.io/port: '9113'
prometheus.io/scrape: 'true'
spec:
containers:
- name: nginx-ingress-infra-nginx-ingress
image: 'nginx/nginx-ingress:1.9.1'
args:
- '-nginx-plus=false'
- '-nginx-reload-timeout=0'
- '-enable-app-protect=false'
- >-
-nginx-configmaps=$(POD_NAMESPACE)/nginx-ingress-infra-nginx-ingress
- >-
-default-server-tls-secret=$(POD_NAMESPACE)/nginx-ingress-infra-nginx-ingress-default-server-secret
- '-ingress-class=infra'
- '-health-status=false'
- '-health-status-uri=/nginx-health'
- '-nginx-debug=false'
- '-v=1'
- '-nginx-status=true'
- '-nginx-status-port=8080'
- '-nginx-status-allow-cidrs=127.0.0.1'
- '-report-ingress-status'
- '-external-service=nginx-ingress-infra-nginx-ingress'
- '-enable-leader-election=true'
- >-
-leader-election-lock-name=nginx-ingress-infra-nginx-ingress-leader-election
- '-enable-prometheus-metrics=true'
- '-prometheus-metrics-listen-port=9113'
- '-enable-custom-resources=true'
- '-enable-tls-passthrough=false'
- '-enable-snippets=false'
- '-ready-status=true'
- '-ready-status-port=8081'
- '-enable-latency-metrics=false'
My ingress configuration of the service name "account":
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
name: account
namespace: infra
resourceVersion: '194790'
labels:
app.kubernetes.io/managed-by: Helm
annotations:
kubernetes.io/ingress.class: infra
meta.helm.sh/release-name: infra
meta.helm.sh/release-namespace: infra
nginx.ingress.kubernetes.io/affinity: cookie
nginx.ingress.kubernetes.io/proxy-buffer-size: 128k
nginx.ingress.kubernetes.io/proxy-buffering: 'on'
nginx.ingress.kubernetes.io/proxy-buffers-number: '4'
spec:
tls:
- hosts:
- account.infra.mydomain.com
secretName: my-default-cert **this is a self-signed certificate with cn=account.infra.mydomain.com
rules:
- host: account.infra.mydomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
serviceName: account
servicePort: 80
status:
loadBalancer:
ingress:
- ip: 123.123.123.123 **redacted**
My account service yaml
kind: Service
apiVersion: v1
metadata:
name: account
namespace: infra
labels:
app.kubernetes.io/instance: infra
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: account
app.kubernetes.io/version: latest
helm.sh/chart: account-0.1.0
annotations:
meta.helm.sh/release-name: infra
meta.helm.sh/release-namespace: infra
spec:
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
selector:
app.kubernetes.io/instance: infra
app.kubernetes.io/name: account
clusterIP: 10.0.242.212
type: ClusterIP
sessionAffinity: ClientIP **just tried to add this setting to the service, but does not work either**
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
status:
loadBalancer: {}
Ok, the issue was not related to any configuration shown above. The debug logs of the nginx pods were full of error messages in regards to the kube-control namespaces. I was removing the Nginx helm chart completely and used the repositories suggested by Microsoft:
https://learn.microsoft.com/en-us/azure/aks/ingress-own-tls
# Create a namespace for your ingress resources
kubectl create namespace ingress-basic
# Add the ingress-nginx repository
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
# Use Helm to deploy an NGINX ingress controller
helm install nginx-ingress ingress-nginx/ingress-nginx \
--namespace ingress-basic \
--set controller.replicaCount=2 \
--set controller.nodeSelector."beta\.kubernetes\.io/os"=linux \
--set defaultBackend.nodeSelector."beta\.kubernetes\.io/os"=linux

K8S baremetal nginx ingress controller not works

I encountered a problem when integrating K8S nginx ingress. I installed the nginx ingress controller and established the testing ingress resources according to the instructions on the document, but I was not able to jump to the normal path. The test serive was normal and Accessible via cluster IP. Am I missing something?
Install script
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
Bare-metal Using NodePort
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/service-nodeport.yaml
Ingress controller is OK
Testing ingress resource
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
app: my-nginx
template:
metadata:
labels:
app: my-nginx
spec:
containers:
- name: my-nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
app: my-nginx
spec:
ports:
- port: 80
protocol: TCP
name: http
selector:
app: my-nginx
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-nginx
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: nginx1.beencoding.com
http:
paths:
- path: /
backend:
serviceName: nginx-1
servicePort: 80
We can see the test nginx pod raised and works fine, I can access the nginx index page by cluster IP
But I can't access nginx1.beencoding.com
Can't access via browser
I have solved the problem by setting hostnetwork: true
It says can't resolve.
Either put the domain in /etc/hosts/ file, or do the curl as follows:
curl -H "Host: nginx1.beecoding.com" IP_ADDRESS
Should work.

Resources