After setting up workloads in EKS, the requirement was to expose the workloads outside the cluster. Here we can use a Kubernetes Ingress resource, which can be used to manage traffic to various Kubernetes Services. To manage the traffic using these ingress resources, we used Ingress-Nginx. It’s an open source ingress controller that’s widely used. Here’s the guide on how to set up ingress-nginx
in an EKS cluster and use AWS Certificate Manager (ACM)
for the TLS termination.
Ingress-Nginx Deployment
We can deploy ingress-nginx
using helm cli or kubectl (Kubectl Manifests). First we need to get the VPC
details and the ACM
Arn
- Get VPC Cidr. Replace
VPC_ID
.
aws ec2 describe-vpcs --vpc-ids VPC_ID --query "Vpcs[0].CidrBlock" --output text```
- Get the ACM Arn. Replace
DOMAIN_NAME
aws acm list-certificates --query "CertificateSummaryList[?DomainName=='DOMAIN_NAME'].CertificateArn" --output text
Helm
- Add
ingress-nginx
helm repo
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginxhelm repo update
- Use the following custom values file. Replace
VPC_CIDR
andACM_ARN
from the values we obtained before
controller: config: http-snippet: | server { listen 2443; return 308 https://$host$request_uri; } proxy-real-ip-cidr: VPC_CIDR use-forwarded-headers: "true" service: enabled: true external: enabled: true annotations: service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "60" service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true" service.beta.kubernetes.io/aws-load-balancer-ssl-cert: ACM_ARN service.beta.kubernetes.io/aws-load-balancer-ssl-ports: https service.beta.kubernetes.io/aws-load-balancer-type: nlb type: LoadBalancer
- Deploy the
ingress-nginx
chart
helm -n ingress-nginx upgrade --install ingress-nginx ingress-nginx/ingress-nginx -f ingress-nginx-values.yaml --create-namespace
Kubectl
- Get the
kubectl
deployment yaml foringress-nginx
with AWS support - Ref
curl -O https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.12.3/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml
- Change the values accordingly:
proxy-real-ip-cidr: XXX.XXX.XXX/XX
- set value toVPC_CIDR
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-west-2:XXXXXXXX:certificate/XXXXXX-XXXXXXX-XXXXXXX-XXXXXXXX
- set value inannotations
toACM_ARN
- Deploy the
kubectl
yaml
kubectl apply -f deploy.yaml
Testing Ingress-Nginx with TLS
Since ingress-nginx
is deployed, we’ll need to wait for all the pods to come up.
kubectl -n ingress-nginx get pods
Get the NLB
hostname that’s assigned to the ingress-nginx-controller
kubernetes service. Add this hostname as the value of an A record in your DNS provider. The A record name should be the domain where you’ll need to access the kubernetes workload.
kubectl -n ingress-nginx get svc ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'
Get the ingress class name used by ingress-nginx
controller. By default the value will be nginx
kubectl get ingressclasses.networking.k8s.io
Now we can deploy the sample workload to test this
apiVersion: v1kind: Podmetadata: name: nginx labels: app: nginxspec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80---apiVersion: v1kind: Servicemetadata: name: nginx-servicespec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 type: ClusterIP---apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: nginx-ingressspec: ingressClassName: nginx # This must match the Ingress Controller's class name rules: - host: SAMPLE_DOMAIN # Replace with your actual domain http: paths: - path: / pathType: Prefix backend: service: name: nginx-service port: number: 80
Now try to access the domain at https://SAMPLE_DOMAIN
. You’ll see the default nginx page. You can also notice how the ssl works at https://SAMPLE_DOMAIN
.