After creating all require resource and config the nginx-ingress controller.
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-api
spec:
replicas: 1
selector:
matchLabels:
app: user-api
strategy: {}
template:
metadata:
labels:
app: user-api
spec:
dnsPolicy: ClusterFirstWithHostNet
hostNetwork: true
containers:
- name: user-api
image: doumeyi/user-api-amd64:1.0
ports:
- name: user-api
containerPort: 3000
resources: {}
---
apiVersion: v1
kind: Service
metadata:
name: user-api
spec:
selector:
app: user-api
ports:
- name: user-api
port: 3000
targetPort: 3000
type: LoadBalancer
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: example.com
http:
paths:
- path: /user-api
backend:
serviceName: user-api
servicePort: 3000
I can view example.com show the 404 not found page, but also can not see example.com/user-api to show any message I build in user-api service.
It seems the nginx-ingress cannot resolve the host name to the internal service, how should I fix it?
If NGINX cannot find a route to your Pod, it should not respond with 404. Instead it should give an 502 (Bad Gateway) AFAIK. I assume the 404 is from your application.
NGINX-Ingress changed behavior in 0.22 as mentioned here
The ingress resource should look like this:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: example.com
http:
paths:
- path: /user-api(/|$)(.*)
backend:
serviceName: user-api
Related
I updated readiness probe in my deployment file and also specify port in ingress, service and deployment.
But my GCE Load Balancer health check is not reflecting the correct path (even I delete and recreate ingress).
Am I missing any configuration?
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
name: custom-app-managed-cert
spec:
domains:
- uat.xyz.com
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
kubernetes.io/ingress.class: "gce"
kubernetes.io/ingress.global-static-ip-name: app-gce-uat-ip
networking.gke.io/managed-certificates: custom-app-uat-managed-cert
spec:
rules:
- host: "uat.xyz.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: custom-app
port:
number: 80
---
apiVersion: v1
kind: Service
metadata:
name: custom-app
spec:
type: LoadBalancer
selector:
app: custom-app
ports:
- port: 80
targetPort: 80
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: custom-app-gke
spec:
replicas: 1
selector:
matchLabels:
app: custom-app
template:
metadata:
labels:
app: custom-app
spec:
serviceAccountName: app-svc
containers:
- name: custom-app-app
image: xxx
imagePullPolicy: Always
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /health
port: 80
env:
- name: PORT
value: "80"
---
I deploy my web service on K3S. I use DuckDNS to access https. i can access my domain with https. But i can't access my web service specific URL.
Here is my yaml files
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: auto-trade-api
spec:
replicas: 1
selector:
matchLabels:
app: auto-trade-api
template:
metadata:
labels:
app: auto-trade-api
spec:
containers:
- name: auto-trade-api
image: image
args: ['yarn', 'start']
resources:
requests:
cpu: '200m'
memory: '200Mi'
limits:
cpu: '200m'
memory: '200Mi'
envFrom:
- secretRef:
name: auto-trade-api
ports:
- containerPort: 3001
restartPolicy: Always
imagePullSecrets:
- name: regcred
Service
kind: Service
metadata:
name: auto-trade-api
spec:
type: "NodePort"
selector:
app: auto-trade-api
ports:
- protocol: TCP
port: 3001
targetPort: 3001
Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: auto-trade-api
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.class: "traefik"
cert-manager.io/cluster-issuer: "letsencrypt"
spec:
tls:
- hosts:
- mydomain
secretName: auto-trade-api-tls
rules:
- host: mydomain
http:
paths:
- path: /*
pathType: Prefix
backend:
service:
name: auto-trade-api
port:
number: 3001
i tried access https://mydomain/users that i made. but only display 404 page not found
I think i did connect each component well.
I try to migrate from Traefik V1 to V2 without the IngressRoute or Middleware.
my requests to /backend/something should be routed to the root of my backend service with /something.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/redirect-regex: /backend$
traefik.ingress.kubernetes.io/redirect-replacement: /backend/
traefik.ingress.kubernetes.io/request-modifier: "ReplacePathRegex: ^/backend/(.*) /$1"
spec:
rules:
- host: demo.myapp.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
serviceName: frontend-app
servicePort: 80
- path: /backend # requests to /backend/something should end up in /something
pathType: ImplementationSpecific
backend:
service:
name: backend-api
port: http
How can I strip that?
At the moment requests to
/backend/something ends up in backend/something/ but should be /something
Thank you in advance
PS: is there a "tool" to monitor or test such requests?
This is a demo deployment I work with:
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend-app
namespace: default
labels:
app: nginx
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
resources:
requests:
cpu: 100m
memory: 100Mi
limits:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 80
name: http
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
spec:
selector:
app: nginx
type: ClusterIP
sessionAffinity: None
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-api
namespace: default
labels:
app: hello-world
spec:
selector:
matchLabels:
app: hello-world
replicas: 1
template:
metadata:
labels:
app: hello-world
spec:
containers:
- name: hello-world
image: rancher/hello-world:latest
resources: {}
ports:
- containerPort: 80
name: http
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: hello-world
namespace: default
spec:
selector:
app: hello-world
type: ClusterIP
sessionAffinity: None
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: production-ingress
namespace: production
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: web, websecure
# usage: namespace-middlewareName#kubernetescrdIsMandatory
traefik.ingress.kubernetes.io/router.middlewares: production-middleware-frontend#kubernetescrd,production-middleware-backend#kubernetescrd
traefik.ingress.kubernetes.io/router.tls: "true"
# cert-manager.io/cluster-issuer: letsencrypt-staging
spec:
rules:
- host: yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend
port:
number: 5000
- path: /backend
pathType: ImplementationSpecific
backend:
service:
name: backend
port:
number: 3000
tls:
- hosts:
- "yourdomain.com"
secretName: yourdomain-com-production-tls
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: middleware-backend
namespace: production
annotations:
kubernetes.io/ingress.class: traefik
spec:
stripPrefix:
prefixes:
- /backend
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: middleware-frontend
namespace: production
annotations:
kubernetes.io/ingress.class: traefik
spec:
stripPrefix:
prefixes:
- /
I am trying to use microservices with my frontend application through nginx ingress controller.
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.48.1/deploy/static/provider/aws/deploy.yaml
above is the command which we have followed to deploy nginx-controller.
reference - https://kubernetes.github.io/ingress-nginx/deploy/#aws
------ My deployment.yaml & service.yaml for integrations-api is as below -------
'''
apiVersion: apps/v1
kind: Deployment
metadata:
name: integrations-api
labels:
app: integrations-api
spec:
replicas: 1
selector:
matchLabels:
app: integrations-api
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: integrations-api
spec:
containers:
- image: "###imagepath####"
imagePullPolicy: Always
name: integrations-api
ports:
- containerPort: 8083
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: integrations-api
annotations:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "tcp,http"
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "###certpath###"
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https"
spec:
type: LoadBalancer
selector:
app: integrations-api
ports:
- name: http
port: 80
targetPort: 8083
protocol: TCP
- name: https
port: 443
targetPort: 8083
protocol: TCP
'''
------ My ingress.yaml looks like this --------
'''
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: integrations-api
servicePort: 80
- path: /
backend:
serviceName: user-api
servicePort: 80
'''
IN my node js integraion-api code we have added testing api path as below
'''
app.get('/camps', (req, res) => {
let obj = {}
res.send(obj);
});
'''
When i am vising endpoint of nginx-controller(here it is load balancer endpoint) https://####NLB-endpoint###/camps
i am getting response.
same configuration like deployment.yaml, service.yaml & nodejs code is written for user-services api. but i am not getting response for user-api
https://####NLB-endpoint###/users
Note, When i am shuffeling the ingress file as below i am getting response of https://####NLB-endpoint###/users but not for https://####NLB-endpoint###/camps. looks inress is taking path which is mentioned in first place only.
'''
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: user-api
servicePort: 80
- path: /
backend:
serviceName: integrations-api
servicePort: 80
'''
Any clue how can i fix this ?
Thanks in advance. it would great help from your side if someone guide us on the same.
This response may be too late. You are trying to creating a path based routing with multiple microservices. In this case, you need to set a path. For user-api, you need to set /user as path and then for integrations-api, you need to specify another path like /camps.
I have done the setup of ALB (Application Load Balancer) using Ingress Controller (version -> docker.io/amazon/aws-alb-ingress-controller:v1.1.8) for my AWS EKS cluster (v 1.20) running with Fargate profile.
I can access my service using the load balancer link:-
http://5e07dbe1-default-nginxingr-29e9-1260427999.us-east-1.elb.amazonaws.com/
I have 2 different services configured in my Ingress as shown below:-
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: "nginx-ingress"
namespace: "default"
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/security-groups: sg-014b302d73097d083
# alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
# alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-east-1:195725532069:certificate/b6a9e691-b807-4f10-a0bf-0449730ecdf4
# alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
# alb.ingress.kubernetes.io/backend-protocol: HTTPS
#alb.ingress.kubernetes.io/load-balancer-attributes: "60"
#alb.ingress.kubernetes.io/rewrite-target: /
labels:
app: nginx-ingress
spec:
rules:
- http:
paths:
# - path: /*
# pathType: Prefix
# backend:
# service:
# name: ssl-redirect
# port:
# number: use-annotation
- path: /foo
pathType: Prefix
backend:
service:
name: "nginx-service"
port:
number: 80
- path: /*
pathType: Prefix
backend:
service:
name: "mydocker-svc"
port:
number: 8080
Now the problem is if I put /foo at the end of LB link then nothing happens and I get 404 not found error:-
Both my services are fine with respective Pods running behind their respective Kubernetes NodePort services but they are not accessible using the Ingress. If I swap the path to /* from /foo for the other service (nginx-service), I can then access that but then it will break my previous service (mydocker-svc).
Please let me know where I'm the mistake so that I can fix this issue. Thank you
ALB Controller:-
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/name: alb-ingress-controller
name: alb-ingress-controller
namespace: kube-system
spec:
selector:
matchLabels:
app.kubernetes.io/name: alb-ingress-controller
template:
metadata:
labels:
app.kubernetes.io/name: alb-ingress-controller
spec:
containers:
- name: alb-ingress-controller
args:
- --ingress-class=alb
- --cluster-name=eks-fargate-alb-demo
- --aws-vpc-id=vpc-0dc46d370e38de475
- --aws-region=us-east-1
image: docker.io/amazon/aws-alb-ingress-controller:v1.1.8
serviceAccountName: alb-ingress-controller
Nginx service:-
apiVersion: v1
kind: Service
metadata:
annotations:
alb.ingress.kubernetes.io/target-type: ip
name: "nginx-service"
namespace: "default"
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
type: NodePort
selector:
app: "nginx"
mydocker-svc:-
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
eks.amazonaws.com/fargate-profile: fp-default
run: mydocker
name: mydocker-svc
annotations:
alb.ingress.kubernetes.io/target-type: ip
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
eks.amazonaws.com/fargate-profile: fp-default
run: mydocker
type: NodePort
status:
loadBalancer: {}
TargetGroups become unhealthy, if the annotation in Kubernetes NodePort service like alb.ingress.kubernetes.io/target-type: IP is missing:-
You can try this out one i am using as reference
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-usermgmt-restapp-service
labels:
app: usermgmt-restapp
annotations:
# Ingress Core Settings
kubernetes.io/ingress.class: "alb"
alb.ingress.kubernetes.io/scheme: internet-facing
# Health Check Settings
alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
alb.ingress.kubernetes.io/healthcheck-port: traffic-port
#Important Note: Need to add health check path annotations in service level if we are planning to use multiple targets in a load balancer
#alb.ingress.kubernetes.io/healthcheck-path: /usermgmt/health-status
alb.ingress.kubernetes.io/healthcheck-interval-seconds: '15'
alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '5'
alb.ingress.kubernetes.io/success-codes: '200'
alb.ingress.kubernetes.io/healthy-threshold-count: '2'
alb.ingress.kubernetes.io/unhealthy-threshold-count: '2'
spec:
rules:
- http:
paths:
- path: /app1/*
backend:
serviceName: app1-nginx-nodeport-service
servicePort: 80
- path: /app2/*
backend:
serviceName: app2-nginx-nodeport-service
servicePort: 80
- path: /*
backend:
serviceName: usermgmt-restapp-nodeport-service
servicePort: 8095
Read more at : https://www.stacksimplify.com/aws-eks/aws-alb-ingress/kubernetes-aws-alb-ingress-context-path-based-routing/