How to integrate Kubernetes with existing AWS ALB?

1/22/2018

I want to use existing AWS ALB for my kubernetes setup. i.e. I don't want alb-ingress-controller create or update any existing AWS resource ie. Target groups, roles etc.

How can I make ALB to communicate with Kubernetes cluster, henceforth passing the request to existing services and getting the response back to ALB to display in the front end?

I tried this but it will create new ALB for new ingress resource. I want to use the existing one.

-- raman.pndy
amazon-ec2
amazon-web-services
docker
kubernetes
microservices

1 Answer

1/23/2018

You basically have to open a node port on the instances where the Kubernetes Pods are running. Then you need to let the ALB point to those instances. There are two ways of configuring this. Either via Pods or via Services.

To configure it via a Service you need to specify .spec.ports[].nodePort. In the default setup the port needs to be between 30000 and 32000. This port gets opened on every node and will be redirected to the specified Pods (which might be on any other node). This has the downside that there is another hop, which also can cost money when using a multi-AZ setup. An example Service could look like this:

---
apiVersion: v1
kind: Service

metadata:
  name: my-frontend
  labels:
    app: my-frontend

spec:
  type: NodePort
  selector:
    app: my-frontend
  ports:
  - port: 8080
    nodePort: 30082

To configure it via a Pod you need to specify .spec.containers[].ports[].hostPort. This can be any port number, but it has to be free on the node where the Pod gets scheduled. This means that there can only be one Pod per node and it might conflict with ports from other applications. This has the downside that not all instances will be healthy from an ALB point-of-view, since only nodes with that Pod accept traffic. You could add a sidecar container which registers the current node on the ALB, but this would mean additional complexity. An example could look like this:

---
apiVersion: extensions/v1beta1
kind: Deployment

metadata:
  name: my-frontend
  labels:
    app: my-frontend

spec:
  replicas: 3

  selector:
    matchLabels:
      app: my-frontend

  template:
    metadata:
      name: my-frontend
      labels:
        app: my-frontend

    spec:
      containers:
      - name: nginx
        image: "nginx"

        ports:
        - containerPort: 80
          hostPort: 8080
-- svenwltr
Source: StackOverflow