Kubernetes Ingress with AWS ALB Ingress Controller
by Nishi Davidson | on 20 NOV 2018 | in Amazon Elastic Kubernetes Service, Open Source | Permalink | Comments | Share
中文版 – Kubernetes Ingress is an api object that allows you manage external (or) internal HTTP[s] access to Kubernetes services running in a cluster. Amazon Elastic Load Balancing Application Load Balancer (ALB) is a popular AWS service that load balances incoming traffic at the application layer (layer 7) across multiple targets, such as Amazon EC2 instances, in a region. ALB supports multiple features including host or path based routing, TLS (Transport layer security) termination, WebSockets, HTTP/2, AWS WAF (web application firewall) integration, integrated access logs, and health checks.
The AWS ALB Ingress controller is a controller that triggers the creation of an ALB and the necessary supporting AWS resources whenever a Kubernetes user declares an Ingress resource on the cluster. The Ingress resource uses the ALB to route HTTP[s] traffic to different endpoints within the cluster. The AWS ALB Ingress controller works on any Kubernetes cluster including Amazon Elastic Container Service for Kubernetes (EKS).
Terminology
We will use the following acronyms to describe the Kubernetes Ingress concepts in more detail:
- ALB: AWS Application Load Balancer
- ENI: Elastic Network Interfaces
- NodePort: When a user sets the
type
field toNodePort
, the Kubernetes master allocates a static port from a range, and each Node will proxy that port (the same port number on every Node) into yourService
.
How Kubernetes Ingress works with aws-alb-ingress-controller
The following diagram details the AWS components that the aws-alb-ingress-controller creates whenever an Ingress resource is defined by the user. The Ingress resource routes ingress traffic from the ALB to the Kubernetes cluster.
Ingress Creation
Following the steps in the numbered blue circles in the above diagram:
- The controller watches for ingress events from the API server. When it finds ingress resources that satisfy its requirements, it begins creation of AWS resources.
- An ALB is created for the Ingress resource.
- TargetGroups are created for each backend specified in the Ingress resource.
- Listeners are created for every port specified as Ingress resource annotation. When no port is specified, sensible defaults (
80
or443
) are used. - Rules are created for each path specified in your ingress resource. This ensures that traffic to a specific path is routed to the correct TargetGroup created.
Ingress Traffic
AWS ALB Ingress controller supports two traffic modes: instance mode and ip mode.
Users can explicitly specify these traffic modes by declaring the alb.ingress.kubernetes.io/target-type annotation on the Ingress and the Service definitions.
- instance mode: Ingress traffic starts from the ALB and reaches the NodePort opened for your service. Traffic is then routed to the container Pods within cluster. The number of hops for the packet to reach its destination in this mode is always two.
- ip mode: Ingress traffic starts from the ALB and reaches the container Pods within cluster directly. In order to use this mode, the networking plugin for the Kubernetes cluster must use a secondary IP address on ENI as pod IP, aka AWS CNI plugin for Kubernetes. The number of hops for the packet to reach its destination in this mode is always one.
Deploy Amazon EKS with eksctl
First, let’s deploy an Amazon EKS cluster with eksctl cli tool.
Install eksctl with Homebrew for macOS users:
brew install weaveworks/tap/eksctl
Create EKS cluster with cluster name “attractive-gopher”
eksctl create cluster --name=attractive-gopher
Go to the “Subnets” section in the VPC Console. Find all the Public subnets for your EKS cluster.
Example:
eksctl-attractive-gopher-cluster/SubnetPublic<USWEST2a>
eksctl-attractive-gopher-cluster/SubnetPublic<USWEST2b>
eksctl-attractive-gopher-cluster/SubnetPublic<USWEST2c>
Configure the Public subnets in the console as defined in this guide. (Most Kubernetes
distributions on AWS already do this for you, e.g. kops)
Deploy AWS ALB Ingress controller
Next, let’s deploy the AWS ALB Ingress controller into our Kubernetes cluster.
Create the IAM policy to give the Ingress controller the right permissions:
- Go to the IAM Console and choose the section Policies.
- Select Create policy.
- Embed the contents of the template iam-policy.json in the JSON section.
- Review policy and save as “ingressController-iam-policy”
Attach the IAM policy to the EKS worker nodes:
- Go back to the IAM Console.
- Choose the section Roles and search for the NodeInstanceRole of your EKS worker node. Example: eksctl-attractive-gopher-NodeInstanceRole-xxxxxx
- Attach policy “ingressController-iam-policy.”
Deploy RBAC Roles and RoleBindings needed by the AWS ALB Ingress controller:
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.0.0/docs/examples/rbac-role.yaml
Download the AWS ALB Ingress controller YAML into a local file:
curl -sS "https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.0.0/docs/examples/alb-ingress-controller.yaml" > alb-ingress-controller.yaml
Edit the AWS ALB Ingress controller YAML to include the clusterName of the Kubernetes (or) Amazon EKS cluster.
Edit the –cluster-name flag to be the real name of our Kubernetes (or) Amazon EKS cluster.
Deploy the AWS ALB Ingress controller YAML:
kubectl apply -f alb-ingress-controller.yaml
Verify that the deployment was successful and the controller started:
kubectl logs -n kube-system $(kubectl get po -n kube-system | egrep -o alb-ingress[a-zA-Z0-9-]+)
You should be able to see the following output:
------------------------------------------------------------------------------- AWS ALB Ingress controller Release: v1.0.0 Build: git-6ee1276 Repository: https://github.com/kubernetes-sigs/aws-alb-ingress-controller -------------------------------------------------------------------------------
Deploy Sample Application
Now let’s deploy a sample 2048 game into our Kubernetes cluster and use the Ingress resource to expose it to traffic:
Deploy 2048 game resources:
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.0.0/docs/examples/2048/2048-namespace.yaml kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.0.0/docs/examples/2048/2048-deployment.yaml kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.0.0/docs/examples/2048/2048-service.yaml
Deploy an Ingress resource for the 2048 game:
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.0.0/docs/examples/2048/2048-ingress.yaml
After few seconds, verify that the Ingress resource is enabled:
kubectl get ingress/2048-ingress -n 2048-game
You should be able to see the following output:
NAME HOSTS ADDRESS PORTS AGE 2048-ingress * DNS-Name-Of-Your-ALB 80 3m
Open a browser. Copy and paste your “DNS-Name-Of-Your-ALB”. You should be to access your newly deployed 2048 game – have fun!
Get Involved
The AWS ALB Ingress controller, a subproject of Kubernetes SIG (Special Interest Group) AWS, is a fully open source project maintained by Yang Yang (@M00nf1sh) and Kraig Amador. Kubernetes SIG-AWS’s technical roadmap is currently steered by three SIG chairs: Nishi Davidson (@nishidavidson), Justin Santa Barbara, and Kris Nova (@krisnova).
AWS ALB Ingress controller has been pegged as an alpha feature in Kubernetes 1.13, due to release early December 2018. The AWS team has also tested the Ingress controller with Amazon EKS that currently supports Kubernetes version 1.10.
More resources: