Search code examples
amazon-web-serviceskubernetes-ingressamazon-eks

AWS Ingress Controller seems to be ignoring host name rules


I am trying to deploy a frontend application to Amazon EKS. The concept is that there will be two deployments as well as two services (frontend-service and stg-frontend-service), one for production and one for staging.

On top of that, there will be an ingress ALB which will redirect traffic based on the hostname. i.e. if the hostname is www.project.io, traffic will be routed to frontend-service and if the hostname is stg-project.io, traffic will be routed to stg-frontend-service.

Here are my deployment and ingress configs

stg-frontend-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: stg-frontend-deployment
  namespace: project
spec:
  replicas: 3
  selector:
    matchLabels:
      app: stg-frontend
  template:
    metadata:
      labels:
        app: stg-frontend
    spec:
      containers:
        - name: stg-frontend
          image: STAGING_IMAGE
          imagePullPolicy: Always
          ports:
            - name: web
              containerPort: 3000
      imagePullSecrets:
        - name: project-ecr

---

apiVersion: v1
kind: Service
metadata:
  name: stg-frontend-service
  namespace: project
spec:
  selector:
    app: stg-frontend
  ports:
  - protocol: TCP
    port: 80
    targetPort: 3000

stg-prod-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend-deployment
  namespace: project
spec:
  replicas: 3
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
        - name: frontend
          image: PRODUCTION_IMAGE
          imagePullPolicy: Always
          ports:
            - name: web
              containerPort: 3000
      imagePullSecrets:
        - name: project-ecr

---

apiVersion: v1
kind: Service
metadata:
  name: frontend-service
  namespace: project
spec:
  selector:
    app: frontend
  ports:
  - protocol: TCP
    port: 80
    targetPort: 3000

ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: project-ingress
  namespace: project
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
spec:
  rules:
  - host: www.project.io
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-service
            port:
              number: 80
  - host: stg.project.io
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: stg-frontend-service
            port:
              number: 80

Later, I have used Route 53 to route traffic from both domain to the ALB.

+----------------+------+---------+-----------------------------------------------------+
|  Record Name   | Type | Routing |               Value/Route traffic to                |
+----------------+------+---------+-----------------------------------------------------+
| www.project.io | A    | Simple  | dualstack.k8s-********.us-west-1.elb.amazonaws.com. |
| stg.project.io | A    | Simple  | dualstack.k8s-********.us-west-1.elb.amazonaws.com. |
+----------------+------+---------+-----------------------------------------------------+

The problem is, ALB ingress is always routing traffic to the first spec rules. In the config above, the first rule is host www.project.io which refers to frontend-service. Whenever I am trying to access www.project.io or stg.project.io, it's showing me a response from frontend-service.

Later, I have switched the rules and put staging rules first, and then it was showing staging service on both domains.

I even created a dummy record like junk.project.io and pointed to the load balancer, it still worked and showed me the same response, even though junk.project.io is not included in my ingress config.

It seems to me that Ingress Config is totally ignoring what the host name is and always returning response from the first rule.


Solution

  • Your host and http values are defined as separate items in the list, try removing the - (hyphen) in front of the http node:

      - host: www.project.io
        http: # I removed the hyphen here
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend-service
                port:
                  number: 80
      - host: stg.project.io
        http: # I removed the hyphen here
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: stg-frontend-service
                port:
                  number: 80