ambassador edge stack mapping is not working - kubernetes-ingress

I am trying to set up the ambassador edge stack in my local Kubernetes (Docker Desktop cluster).
After all deployment, I checked the ambassador namespace and everything is working as expected. Moreover, I have my deployment (pod and services) working.I have changed the ambassador edge-stack service to nodeport so I can access and test locally. also, I have added the url in my HOST file.
Now, Here is the detail.
kubectl get svc -n ambassador
kubectl get svc -n sample-on-ambassador-edgestack
edgestack-listener yaml:
--------------------------
apiVersion: getambassador.io/v3alpha1
kind: Listener
metadata:
name: my-listener-80
namespace: sample-on-ambassador-edgestack
spec:
port: 80
protocol: HTTP
securityModel: XFP
hostBinding:
namespace:
from: ALL
apiVersion: getambassador.io/v3alpha1
kind: Listener
metadata:
name: my-listener-8080
namespace: sample-on-ambassador-edgestack
spec:
port: 8080
protocol: HTTP
securityModel: XFP
hostBinding:
namespace:
from: ALL
edgestack-binding yaml
-------------------------
apiVersion: getambassador.io/v3alpha1
kind: Mapping
metadata:
name: my-mappingrules
namespace: sample-on-ambassador-edgestack
spec:
hostname: "local.edgestack.com"
prefix: /apple/
service: my-apple-service.sample-on-ambassador-edgestack
NOTE: I have used Service: pod.service form above.
With this, I am getting edgestack home page with http://local.edgestack.com
but If I type: local.edgestack.com/apple/ I am getting 404 error page.
same with curl comamnd:
curl -i http://local.edgestack.com:32510/apple/
HTTP/1.1 404 Not Found
date: Thu, 02 Dec 2021 01:51:48 GMT
server: envoy
content-length: 0

Your issue has nothing to do with namespacing but rather is that you are accessing the service on a NodePort and are therefore including the port in the host of your curl request but not configuring Emissary to account for that.
If you were to send a curl with the -v flag set, you would see that this request has > Host: local.edgestack.com:32510 which is not the same as local.edgestack.com which your Emissary Ingress is expecting. Since the hostname of the incoming request does not match the Mapping.spec.hostname you have configured, Emissary is not finding a matching route and returning a 404.
You can get around this by doing a glob in the Mapping.spec.hostname so that it matches local.edgestack.com and any ports that follow
apiVersion: getambassador.io/v3alpha1
kind: Mapping
metadata:
name: my-mappingrules
namespace: sample-on-ambassador-edgestack
spec:
hostname: "local.edgestack.com*"
prefix: /apple/
service: my-apple-service

Related

Getting error while apply ingress resource: zone is too small

I am new to Kubernetes. I have create simple cluster with 1 master and 1 worker nodes(both running in 2 different VMs). Additionally there is HA proxy setup in a separate VM.
Client Version: v1.24.0
Kustomize Version: v4.5.4
Server Version: v1.26.1
I have setup NGINX ingress controller using manifests(https://docs.nginx.com/nginx-ingress-controller/installation/installation-with-manifests/).
When I try to apply ingress resource with rules I am getting the error:
Configuration for default/i1 was added or updated ; but was not applied: error reloading NGINX for default/i1: nginx reload failed: command /usr/sbin/nginx -s reload -e stderr stdout: "" stderr: "2023/02/06 12:49:28 [emerg] 30#30: zone \"default-i1-sim.daniyar.uk-first-web-app-service-80\" is too small in /etc/nginx/conf.d/default-i1.conf:4\n" finished with error: exit status 1
My ingress resource:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: i1
spec:
rules:
- host: sim.daniyar.uk
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: first-web-app-service
port:
number: 80
IngressClass yaml:
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
spec:
controller: nginx.org/ingress-controller
Let me know if you need more info
Thanks
Found a solution.
In my case I had to disable zones in NGINX config by using annotation:
nginx.org/upstream-zone-size: "0"
in my ingress resource file.

Exposing AKS cluster application using ingress

I am trying to expose my application inside the AKS cluster using ingress:
It creates a service and an ingress but somehow does not assign an address to the ingress. What could be a possible reason for this?
apiVersion: apps/v1
kind: Deployment
metadata:
name: dockerdemo
spec:
replicas: 1
selector:
matchLabels:
app: dockerdemo
template:
metadata:
labels:
app: dockerdemo
spec:
nodeSelector:
"kubernetes.io/os": linux
containers:
- name: dockerdemo
image: devsecopsacademy/dockerapp:v3
env:
- name: ALLOW_EMPTY_PASSWORD
value: "yes"
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
ports:
- containerPort: 80
name: redis
apiVersion: v1
kind: Service
metadata:
name: dockerdemo-service
spec:
type: ClusterIP
ports:
port: 80
selector:
app: dockerdemo
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress15
annotations:
kubernetes.io/ingress.class: addon-http-application-rounting
spec:
rules:
host: curefirsttestapp.cluster15-dns-c42b65ee.hcp.westeurope.azmk8s.io
http:
paths:
path: /
pathType: Prefix
backend:
service:
name: dockerdemo-service
port:
number: 80
Well, first make sure your application is up and functionning inside your K8s Cluster using a port-forword to your localhost
kubectl -n $NAMESPACE port-forward svc/$SERVICE :$PORT
if app is reachable and your call are getting back 200 Status, you can now move to the ingress part:
Make sure ingress controller is well installed under your services
kubectl -n $NAMESPACE get svc
Add a DNS record in your DNS zone which maps your domain.com to ingress controller $EXTERNAL_IP
Take a look at the ingress you created for your $SERVICE
kubectl -n $NAMESPACE get ingress
At this stage, if you application is well running and also the the ingress is well set, the app should be reachable trough domain.com, otherwise we'll need further debugging.
Make sure you have an ingress controller deployed. This is a load balancer service which can have either a public or private ip depending on your situation.
Make sure you have an ingress definition which has a rule to point to your service. This is the metadata which will tell your ingress controller how to route requests to its ip address. These routing rules can contain how to handle paths like strip, exact, etc....

Allow Azure Application Gateway to route all sub paths in AKS

I have AKS configured with Azure Application Gateway as my ingress.
I am trying to deploy a .net core Angular app to a path within the cluster. I would like to access the app on http://<cluster ip>/app1.
My kubernetes deployment (including ingress settings) is as follows:
apiVersion: v1
kind: Pod
metadata:
name: web-app-1
labels:
app: web-app-1
spec:
containers:
- image: "xxx.azurecr.io/web-app-1:latest"
name: web-app-1
imagePullPolicy: Always
ports:
- containerPort: 80
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: web-app-1
spec:
selector:
app: web-app-1
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web-app-1
annotations:
kubernetes.io/ingress.class: azure/application-gateway
spec:
rules:
- http:
paths:
- path: /app1
backend:
serviceName: web-app-1
servicePort: 80
In the Angular app itself, I have left <base href="/" /> in index.html. However, I have amended the build to now be ng build --base-href /app1/"
Issue
When this is deployed and I browse to http://<cluster ip>/app1 then it loads the index.html file. However it returns a 404 for all the additional scripts e.g. 404 on http://<cluster ip>/app1/main-es2015.9ae13a2658e759db61f5.js
The issue could be with how I've configured Angular, but browsing to http://<cluster ip>/app1/index.html returns a 404 when I know it can be accessed just using /app1/.
I believe the issue is that Application Gateway is not routing requests properly for anything after /app1/. How can I get it to allow sub routes through (i.e. the scripts)?
Thanks
Got this working now. If I looked at the 404 response headers it says it was from kestrel, so was hitting the dotnet core api, so it needs configuring there. All the changes I made were:
Client:
Leave the base href as / e.g.
Add the base href to the build argument e.g. ng build --base-href /app1/"
In Configure of Startup.cs, add app.UsePathBase("/app1"); I do this in the else of env.IsDevelopment().
Application Gateway:
Change the path for the rules to - path: /app1*. I didn't have the asterisk so wasn't routing all subsequent routes.
You could also do something like this
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: appgw-ingress
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/backend-path-prefix: "/"
spec:
rules:
- http:
paths:
- path: /api/*
....
Where you are updating the routing prefix form "/" to "/api/*" . Specifically this annotation
appgw.ingress.kubernetes.io/backend-path-prefix: "/"

How to visualize my web application with browser using Kubernetes Nginx Ingress?

I am following this web site to develop an API with Nginx Ingress. When I use curl command it works !
curl -v -k -H "Host: myServiceA.foo.org" http:<IP_ADDRESS_INGRESS_NGINX>:80
Now I would like to use a browser like Chrome or Firefox but I don't find any way to do it knowing that http:<IP_ADDRESS_INGRESS_NGINX>:80 doesn't work without header.
Do you know how to do please ?
Regards
It's not working because you've configured the host field in ingress yaml.
Using the same yaml from Nginx docs you've posted:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-myServiceA
annotations:
# use the shared ingress-nginx
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: myServiceA.foo.org <== HERE
http:
paths:
- path: /
backend:
serviceName: myServiceA
servicePort: 80
The ingress will only accept the connection and forwarding the request to your service if the request contains the host myServiceA.foo.org.
You could test it editing the /etc/hosts of your machine e pointing to the nginx ingress ip:
File /etc/hosts
<INGRESS_IP> myServiceA.foo.org
Or another option is remove the field host in this way the ingress will accept requests coming from the Nginx ingress ip, like this yaml:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: echo-svc
servicePort: 80

Kubernetes service dns resolution returning wrong IP

I have a simple MYSQL pod sitting behind a MYSQL service.
Additionally I have another pod that is running a python process that is trying to connect to the MYSQL pod.
If I try connecting to the IP address of the MYSQL pod manually from the python pod, everything is A-OK. However if I try connecting to the MYSQL service then I get an error that I can't connect to MYSQL.
grant#grant-Latitude-E7450:~/k8s/objects$ kubectl describe pod mysqlpod
Name: mysqlpod
Namespace: default
Node: minikube/192.168.99.100
Start Time: Fri, 20 Jan 2017 11:10:50 -0600
Labels: <none>
Status: Running
IP: 172.17.0.4
Controllers: <none>
grant#grant-Latitude-E7450:~/k8s/objects$ kubectl describe service mysqlservice
Name: mysqlservice
Namespace: default
Labels: <none>
Selector: db=mysqllike
Type: ClusterIP
IP: None
Port: <unset> 3306/TCP
Endpoints: 172.17.0.5:3306
Session Affinity: None
No events.
grant#grant-Latitude-E7450:~/k8s/objects$ kubectl describe pod basic-python-model
Name: basic-python-model
Namespace: default
Node: minikube/192.168.99.100
Start Time: Fri, 20 Jan 2017 12:01:50 -0600
Labels: db=mysqllike
Status: Running
IP: 172.17.0.5
Controllers: <none>
If I attach to my python container and do an nslookup of the mysqlservice, then I'm actually getting the wrong IP. As you saw above the IP of the mysqlpod is 172.17.0.4 while nslookup mysqlservice is resolving to 172.17.0.5.
grant#grant-Latitude-E7450:~/k8s/objects$ k8s exec -it basic-python-model bash
[root#basic-python-model /]# nslookup mysqlservice
Server: 10.0.0.10
Address: 10.0.0.10#53
Name: mysqlservice.default.svc.cluster.local
Address: 172.17.0.5
I'm fairly new to kubernetes, but I've been banging my head on this issue for a few hours and I can't seem to understand what I'm doing wrong.
So this was the exact correct behavior but I just misconfigured my pods.
For future people who are stuck:
The selector defined in a kubernetes service must match the label of the pod(s) you wish to serve. IE) In my MySqlService.yaml file I have the name selector for "mysqlpod":
apiVersion: v1
kind: Service
metadata:
name: mysqlservice
spec:
clusterIP: None
ports:
- port: 3306
targetPort: 3306
selector:
name: mysqlpod
Thus in my MySqlPod.yaml file I need an exactly matching label.
kind: Pod
apiVersion: v1
metadata:
name: mysqlpod
labels:
name: mysqlpod
spec:
...
For anyone coming again here, please check #gnicholas answer, but also make sure that clusterIP: None is correctly set.
I happened to indent clusterIP: None too much in the .yml file and the command was ignored by Kubernetes therefore clusterIP was mistakenly assigned causing the wrong IP issue.
Be aware that the validation won't throw any error, but will silently ignore it.