Home > OS >  Angular POD intercommunication with spring boot backend POD via clusterIP service
Angular POD intercommunication with spring boot backend POD via clusterIP service

Time:07-27

i did my kubernetes setup using minikube on my ubuntu machine. I started minkube cluster and am able to start front-end and backend PODs and correspondingly their services (Type- ClusterIP) as well.

I have setup Ingress as well which allowing me to hit the Front-end service(Angular codebase running on Nginx).

Issue i am facing is i am able to hit the front-end POD through Ingress but front-end POD not able to call the backend POD (Having code on agnular side which tries to invoke backend api)

Angular side code, base URL defined as:

export class HeroService {

  private baseUrl = 'http://backend-cluster-ip-service';  
  private apiUrl = `${this.baseUrl}/heroapi/heroes`;

  constructor(private http: HttpClient, private messageService: MessageService) { }

  httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json' })
  };

  /** GET heroes from the server */
  getHeroes(): Observable<Hero[]>{
    /* const heroes = of(HEROES);
    return heroes; */
    return this.http.get<Hero[]>(this.apiUrl)
    .pipe(
      catchError(this.handleError<Hero[]>('getHeroes', []))
    );
  }

Getting below issue while trying to invoke backend API.

CORS issue

I would like to make it clear i already enabled the CORS on backend side, please check the code below

 @Configuration
 public class CorsConfig {

 @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("*");
            }
        };
    }
}

Please see below configuration files for PODS, SERVICES, INGRESS and Docker files for both front-end and backend.

Angular Docker File(Dockerfile.prod):

#stage 1
FROM node:16-alpine as node
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build --prod

#stage 2
FROM nginx:alpine
COPY --from=node /app/dist/sample_angular_first_app /usr/share/nginx/html

Backend Docker file(Dockerfile.prod):

FROM adoptopenjdk/openjdk11:jre-11.0.11_9-alpine
WORKDIR /app
ARG JAR_FILE=./target/demo-0.0.1-SNAPSHOT.jar
COPY ${JAR_FILE} ./hero_app.jar
EXPOSE 8081
ENTRYPOINT ["java","-jar","hero_app.jar"]

Angular(Front-end) Deployment Config file(client-deployment.yaml):

apiVersion: apps/v1
kind: Deployment
metadata:
    name: client-deployment
spec:
    replicas: 1
    selector:
        matchLabels:
            component: web
    template:
        metadata:
            labels:
                component: web
        spec:
            containers:
                - name: client
                  image: techlearning205docker/angular_hero_app_front_end:temp6

Spring-boot(Back-end) Deployment Config file(backend-deployment.yaml):

apiVersion: apps/v1
kind: Deployment
metadata:
    name: backend-deployment
spec:
    replicas: 1
    selector:
        matchLabels:
            component: backend-server
    template:
        metadata:
            labels:
                component: backend-server
        spec:
            containers:
                - name: hero-backend
                  image: techlearning205docker/heroapp_back_end:temp2
                  ports:
                  - containerPort: 8081

Angular(Front-end) SERVICE Config file(client-cluster-ip-service.yaml):

apiVersion: v1
kind: Service
metadata:
  name: client-cluster-ip-service
spec:
  type: ClusterIP
  ports:
    - port:  3050
      targetPort: 80
  selector:
    component:  web

Spring boot(Back-end) SERVICE Config file(backend-cluster-ip-service.yaml):

apiVersion: v1
kind: Service
metadata:
  name: backend-cluster-ip-service
spec:
  type: ClusterIP
  ports:
    - port:  3051
      targetPort: 8081
  selector:
    component:  backend-server

Ingress config file(ingress-service.yaml)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
    name: ingress-service
    annotations:
        kubernetes.io/ingress.class: 'nginx'
        nginx.ingress.kubernetes.io/use-regex: 'true'
        nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - http:
        paths:
          - path: /?(.*)
            # UPDATE PATH
            pathType: Prefix
            # ADD PATHTYPE
            backend:
              service:
                # UPDATE SERVICE FIELDS
                name: client-cluster-ip-service
                port:
                  number: 3050

Please kindly help me to provide solution how one POD communicates with another POD if service type is CLUSTER IP, specifically for my case i have mentioned above.

CodePudding user response:

I got my above posted query resolved!

  • Above issue i was facing due to the fact, we can not access the CLUSTER IP service (backend-cluster-ip-service) outside of cluster.
  • My assumption was we would be able to hit the One POD to another(if we try to invoke REST API(spring boot applicaiton running in another POD) from FrontEnd POD)
  • Above point is actually true when we hit request from within POD itself
  • But in case of FrontEnd POD(Angular code) its not happening due to below mentioned reasons
  • Since Angular is single page application, when we are hitting Url and request first recieved at Frontend side, whatever visible in browser that code is actually NOW on broswer side not on kubernetes cluster that means its on your local browser, Now when applicaiton tries to hit the REST api to some other server, Now this request actually being sent from browser(outside of the cluster) not from with in cluster.
  • That's the reason browser not able to resolve this request "http://backend-cluster-ip-service"

TO Resolve the above issue, have simple workaround

  • The way we pass the request to front end(Angular POD) using Ingress
  • Pass the backend via Ingress too.
  • Ingress should be intelligent enough to identify which request is for Angular POD and which is for Backend POD.

Below is the updated Ingress configuration file i have used.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
    name: ingress-service
    annotations:
        kubernetes.io/ingress.class: 'nginx'
        nginx.ingress.kubernetes.io/use-regex: 'true'
        #nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - http:
        paths:
          - path: /
            # UPDATE PATH
            pathType: Prefix
            # ADD PATHTYPE
            backend:
              service:
                # UPDATE SERVICE FIELDS
                name: client-cluster-ip-service
                port:
                  number: 3050
    - http:
        paths:
          - path: /heroapi
            # UPDATE PATH
            pathType: Prefix
            # ADD PATHTYPE
            backend:
              service:
                # UPDATE SERVICE FIELDS
                name: backend-cluster-ip-service
                port:
                  number: 3051

I have also updated my Angular code

  • private baseUrl = 'http://backend-cluster-ip-service';

  • Update base url on angular side code with cluster ip in my case it was minikube ip(private baseUrl = 'http://192.168.49.2'; )

  • to avoid harcoding of cluster ip as it could change, we should handled it dynamically.

If some one wants to try my above given configuration then please update the Angular POD deployment config image as well -> techlearning205docker/angular_hero_app_front_end:minikube_ip_1

  • Related