I am trying to deploy two very basic services (Spring Boot) with an Ingress that has to redirect the traffic depending on the path. Very basic example of Ingress use, but I can't understand after hours and hours why this configuration won't work.
First controller, exposed to port 8095:
@RestController
public class MainController {
private Logger logger = LoggerFactory.getLogger(MainController.class);
@GetMapping({"/", ""})
public String getDefault(HttpServletRequest request) {
logger.debug("URL: ", makeUrl(request));
return "Root reached: " + makeUrl(request);
}
@GetMapping("/foo")
public String getSubPath(HttpServletRequest request){
logger.debug("URL: ", makeUrl(request));
return "First sub path reached: " + makeUrl(request);
}
@GetMapping("/foo/test")
public String getSubSubPath(HttpServletRequest request){
logger.debug("URL: ", makeUrl(request));
return "First sub sub path reached: " + makeUrl(request);
}
@GetMapping("/foo/health/check")
public String getHealthCheck(HttpServletRequest request) {
return "Health check passed: " + makeUrl(request);
}
private String makeUrl(HttpServletRequest request) {
return request.getRequestURL().toString() + "?" + request.getQueryString();
}
}
Second controller, exposed to port 8080:
@RestController
public class MainController {
private Logger logger = LoggerFactory.getLogger(MainController.class);
@GetMapping({"/bar/", "/bar"})
public String getDefault(HttpServletRequest request) {
logger.debug("URL: ", makeUrl(request));
return "Root reached: " + makeUrl(request);
}
@GetMapping("/bar/test")
public String getSubPath(HttpServletRequest request){
logger.debug("URL: ", makeUrl(request));
return "First sub path reached: " + makeUrl(request);
}
@GetMapping("/bar/test/subsubpath")
public String getSubSubPath(HttpServletRequest request){
logger.debug("URL: ", makeUrl(request));
return "First sub sub path reached: " + makeUrl(request);
}
@GetMapping("/bar/health/check")
public String getHealthCheck(HttpServletRequest request) {
return "Health check 2 passed: " + makeUrl(request);
}
private String makeUrl(HttpServletRequest request) {
return request.getRequestURL().toString() + "?" + request.getQueryString();
}
}
As we can see the endpoints of the controllers simply print some message and the URL, just to know that they are reached from outside of the cluster in which there is the Ingress.
Deployment file for kubernetes:
apiVersion: apps/v1
kind: Deployment
metadata:
name: prova1-deployment
spec:
selector:
matchLabels:
app: deploy1
replicas: 1
template:
metadata:
labels:
app: deploy1
spec:
imagePullSecrets:
- name: gitlab-registry-prova
containers:
- name: prova1-deploy
image: "registry.gitlab.com/giuxg97/reep/test1-deploy"
ports:
- containerPort: 8095
---
apiVersion: v1
kind: Service
metadata:
name: prova1-service
spec:
selector:
app: deploy1
ports:
- protocol: TCP
port: 60000
targetPort: 8095
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: prova2-deployment
spec:
selector:
matchLabels:
app: deploy2
replicas: 1
template:
metadata:
labels:
app: deploy2
spec:
imagePullSecrets:
- name: gitlab-registry-prova
containers:
- name: prova2-deploy
image: "registry.gitlab.com/giuxg97/reep/test2-deploy"
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: prova2-service
spec:
selector:
app: deploy2
ports:
- protocol: TCP
port: 8090
targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
# If the class annotation is not specified it defaults to "gce".
kubernetes.io/ingress.class: "gce"
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: prova1-service
port:
number: 60000
- path: /bar
pathType: Prefix
backend:
service:
name: prova2-service
port:
number: 8090
The images are taken from my private container registry on gitlab and they work as I can see from the logs of the pod after the deployment.
This is now the situation:
So the only service that seems to be reached is the first one, but also in this case I cannot see the subpaths, but I don't know why also after have read more documentations..
I hope you can help me! Thank you in advance
Hi and welcome to Stackoverflow.
For the first issue -
Your ingress definition creates rules that proxy traffic from the {path} to the {backend.serviceName}{path}. One of the possible reasons why path could not be found is that /foo is proxied to app-service: 60000/foo but you're intending on serving traffic at the ‘/’ root.
Try adding this annotation to your ingress resource:
nginx.ingress.kubernetes.io/rewrite-target: /
Source: https://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/rewrite
If that doesn’t resolve the issue, the problem would likely be in your handler method for ‘/foo’ and other subpaths in your spring framework.
For the second issue -
Use Curl command (Curl -D- -s -o/dev/null <<url>>)
to check if you’re able to reach the particular URL (where you’re getting a bad response) using node ip on the backend internally (without going through the Ingress ).
If you’re unable to reach the URL internally, the problem again should be lying with mapping configuration in your spring framework.
If you’re able to reach the URL internally, check the services you created in the deployment file for kubernetes. You can also try changing the deployment port and service port of troubled deployment.
Refer here for detailed instructions on deployment file configuration for GKE -