I have developed a spring boot app (User Registration app) that has one rest API. The rest API inserts the data in a MySQL.
The application and database have been deployed in GCP Kubernetes and everything was working fine as I was using network load balancer.
Now I am trying to use NGINX Ingress Controller and Path-based Ingress routing. A network load balancer is pointing to NGINX Ingress Controller and Load Balancer IP is tagged to a wild card host name in Cloud DNS.
From PostMan application whenever I am trying to hit the "User Registration App" using the DNS url it's throwing an error:
<html>
<head>
<title>405 Not Allowed</title>
</head>
<body>
<center>
<h1>405 Not Allowed</h1>
</center>
<hr>
<center>openresty</center>
</body>
</html>
I am trying to provide all the details I have right. Can provide more details if required. I am not able to understand why NGINX server is throwing "405 Not allowed error".
User Registration Spring Boot App
Spring Boot App Controller - POST method receive the input data
NGINX Controller
Followed the steps mentioned here: https://kubernetes.github.io/ingress-nginx/deploy/#detect-installed-version
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
Ingress Controller Service
Kubernetes Services:
Services Running in Kubernetes Cluster - Refer Yellow marked
Kubernetes Pods:
Pods running in Kubernetes Cluster - Refer Yellow marked
Ingress YML:
`
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: fanout-ingress
namespace: xyz-product
labels: # Labels that will be applied to this resource
app: prod-user-reg-app
annotations:
kubernetes.io/ingress.class: "nginx"
ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS"
spec:
rules:
- host: test.apps.myproduct.com
http:
paths:
- path: /user-reg/create/*
backend:
serviceName: prod-user-reg-create-app
servicePort: 8081`
Kubctl Describe Ingress
GCP Cloud DNS
How do solve the issue? And where is the problem? In NGINX Controller service?
Please help.
The resolution is here. Changed the URL path and used a registered domain to access via the internet.
https://github.com/kubernetes/ingress-nginx/issues/4772 and
https://github.com/kubernetes/ingress-nginx/issues/4776
Related
I am trying to integrate traefik ingress route with middleware (forward-auth) for wss (secure websocket protocol).
For https requests ingressRoute works fine with forward-auth,
but for wss its not reaching to forward-auth, it's bypassing the middleware.
Tried many ingressRoutes with different pathprefix so that it can route to specific middleware which will forward to helidon app for authentication.
I am trying to setup ForwardAuth for wss incoming requests in traefik Ingress, but it's forwarding/bypassing to actual server without reaching to middleware, same thing works fine for usual https calls.
My websocket url: wss://ip:443/ws/guest
How to fix wss traffic for ingressRoute?
IngressRoute.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
annotations:
kubernetes.io/ingress.class: traefik
name: traefik-tls
namespace: sample-domain1-ns
spec:
entryPoints:
- websecure
routes:
- kind: Rule
match: PathPrefix(`/ws`)
middlewares:
- name: test-auth-tls
namespace: sample-domain1-ns
services:
- kind: Service
name: sample-domain1-cluster
port: 8001
tls:
certResolver: default
forward-auth.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-auth-tls
namespace: sample-domain1-ns
spec:
headers:
customRequestHeaders:
X-Forwarded-Proto: https
forwardAuth:
address: https://sample-domain1-lb.sample-domain1-ns.svc.cluster.local:8080/auth
tls:
insecureSkipVerify: true
It seem's like, some forward-auth configuration parameter's are require for websocket.
Please try with authRequestHeaders, authResponseHeaders (https://doc.traefik.io/traefik/middlewares/http/forwardauth/).
You tagged this question with helidon, and while it's great if you're using Helidon I'm not seeing how your issue relates to Helidon specifically, rather than (as you described) ingress set-up, etc. Please correct me if I've missed a Helidon aspect here. And apart from that, I'm sorry, I don't have any suggestions for you.
I have react based UI application running on kubernetes with root contextPath (/). When I do kubectl port-forward svc/my-ui-app 8080:8080 and then launch the application on http://localhost:8080, everything works fine.
Now I want to use spring cloud gateway to route to my application. I configured the root url (/) and /apppath like below
spec:
routes:
- filters:
- RewritePath=/apppath(?<segment>/?.*), $\{segment}
predicates:
- Path=/apppath/**
- predicates:
- Path=/
service:
name: my-ui-app
So my expection is to have http://my-domain and http://my-domain/apppath both to route to my ui application.
Whats happening is when I use http://my-domain/apppath, when the ui app internally refers to the index.js (and other image files), the url used for that evaluates to http://my-domain/apppath/index.js automatically and spring cloud gateway is able to load these files as it matches the route /apppath/** and is able to route to my application.
The problem is with the root url http://my-domain. When I hit this, the url to fetch the index.js (and images etc) evaluates to http://my-domain/index.js and spring cloud gateway does not know where to route it to as there is no route mapped for /index.js.
What do I need to do to make http://my-domain work without having to change the application code to have a contextPath explicitly set?
Problem statement :
I have deployed a spring boot app which when on starting always uses default compute engine service account credentials to authenticate the app , i have a created a seperate service account and key but not able to replace the default one. i tried specifying the new service account in deployement.yaml by using "serviceAccountName" field but still got the error saying service account eg :"xyz" not found.
serviceAccountName: {{ .Values.serviceAccountName }}
so how can i override default service account of compute engine with a specific service account and define it in deployment.yaml.
if i add the credentials of new service account in app code base it will work but that is not a best practice to do so , please someone help me on resolving this issue
snippet of my deployment.yaml file:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: helloworld
appVersion: {{ .Values.appVersion }}
name: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
environment: {{ .Values.environment }}
spec:
containers:
- name: helloworld
image: {{ .Values.imageSha }}
imagePullPolicy: Always
securityContext:
allowPrivilegeEscalation: false
runAsUser: 1000
ports:
- containerPort: 8080
env:
- name: SPRING_CONFIG_LOCATION
value: "/app/deployments/config/"
volumeMounts:
- name: application-config
mountPath: "/app/deployments/config"
readOnly: true
volumes:
- name: application-config
configMap:
name: {{ .Values.configMapName }}
items:
- key: application.properties
path: application.properties
I think you should use Workload Identity which allows to access Google Cloud from outside.
Workload Identity is the recommended way to access Google Cloud services from applications running within GKE due to its improved security properties and manageability. For information about alternative ways to access Google Cloud APIs from GKE, refer to the alternatives section below.
Above guide is well described and I think it should resolve your issue.
For additional example, you can check one of the Community Tutorial - Using Kubernetes Workload Identity for client-server authorization.
In GKE, the Workload Identity feature allows these identities to also be associated with IAM service accounts. This allows a pod running as a Kubernetes service account to act as the associated service account for authorized access to Google APIs and to services that verify identity based on Google Cloud-specific OIDC.
Both docs have examples which should help you to adjust Workload Identity to your needs.
I have a kubernetes cluster on amazon ews on which I intend to run multiple applications.
I have multiple services which make up one such application and I want to expose them to the internet using an amazon load balancer (elb). I want to use the ELB because I don't want to use port 80 directly as many applications share this port and I want each one of them to define their ingress resource independent of others.
I read about kubernetes ingress resources and thought that is exactly what I'm looking for. However I didn't manage to expose it through a service with load balancer. Now when I read the documentation Services are meant to expose pods but an ingress is:
An API object that manages external access to the services in a cluster, typically HTTP.
Is what I'm trying to do possible or did I not grasp some concept and trying to do something impossible or wrong?
My code:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
labels:
id: ingress
spec:
rules:
- http:
paths:
- path: /api/devices
backend:
serviceName: device-management
servicePort: 3001
- path: /api/datasources
backend:
serviceName: data-acquisition
servicePort: 3001
- path: /auth,/account,/api/tenants,/api/users
backend:
serviceName: device-management
servicePort: 3001
## TODO: Find out how to add subdomain entry for auth.domain and s3.domain
---
apiVersion: v1
kind: Service
metadata:
name: ingress
labels:
id: ingress
spec:
type: LoadBalancer
ports:
- name: http
port: 80
targetPort: 80
- name: https
port: 443
targetPort: 443
selector:
id: ingress
Output from kubectl describe service ingress contains
Endpoints: none
The problem is that I didn't install an ingress controller. The documentation states:
You need an Ingress controller to satisfy an Ingress, simply creating the resource will have no effect.
The ingress controller creates an nginx pod and a service (load balancer) which will then implement the rules described in all ingress resources. The installation guide gives further information on how to install it on different platforms.
The ingress controller replaces the service which I desribed above and implements all ingress resources desribed in the cluster.
I managed to have ribbon dynamically discover instances in a k8s cluster using kubeflix and spring-cloud-kubernetes
This was when I manually used Ribbon to communicate between my microservices.
Zuul automatically uses Ribbon for the routes defined in its configuration.
Has anyone managed to enable Ribbon discovery for Zuul? I think I would need to override the instance of LoadBalancer for each of the routes. Any ideas how to do that?
That was actually quite easy. You only need to specify the NIWSServerListClassName, the k8s namespace and the k8s port name in the Ribbon configuration:
service-name:
ribbon:
NIWSServerListClassName: io.fabric8.kubeflix.ribbon.KubernetesServerList
KubernetesNamespace: uat
PortName: tcp80 #make sure you this matches the port name in the k8s service (kubectl describe svc service-name)
Then the Zuul route can refer to the service:
zuul:
routes:
rm-data-store:
path: /foo/**
retryable: true
service-id: service-name