安裝AWS Load Balancer Controller

身為DevOps工程師
9 min readNov 12, 2022

--

之前在使用GCP GKE的時候,不需要特別做設定,直接在GKE上建立ingress都會自動在GCP上建立出ALB。但這次在使用EKS的過程中,就沒有這麼順利了。

紀錄下AWS如果要在建立ingress時,自動建立出ALB所需要的步驟。

Photo by Call Me Fred on Unsplash

建立IAM Policy

US-East 或US-West 請下載此json

curl -o iam_policy_us-gov.json <https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.4/docs/install/iam_policy_us-gov.json>
mv iam_policy_us-gov.json iam_policy.json

其他請下載

curl -o iam_policy.json <https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.4/docs/install/iam_policy.json>

建立iam policy

aws iam create-policy \\
--policy-name AWSLoadBalancerControllerIAMPolicy \\
--policy-document file://iam_policy.json

建立 iamserviceaccount, 1122233445那段請去複製 AWSLoadBalancerControllerIAMPolicy 的arn。

eksctl create iamserviceaccount \\
--cluster=aws-rd-develop \\
--namespace=kube-system \\
--name=aws-load-balancer-controller \\
--role-name "AmazonEKSLoadBalancerControllerRole" \\
--attach-policy-arn=arn:aws:iam::1122233445:policy/AWSLoadBalancerControllerIAMPolicy \\
--approve

如果EKS沒有開啟IAM OIDC provider,噴出了以下Error。

Error: unable to create iamserviceaccount(s) without IAM OIDC provider enabled

請執行以下開啟 IAM OIDC provider

eksctl utils associate-iam-oidc-provider \\
--cluster aws-rd-develop \\
--approve

建立AWS Load Balancer Controller

helm install aws-load-balancer-controller eks/aws-load-balancer-controller \\
-n kube-system \\
--set clusterName=aws-rd-develop \\
--set serviceAccount.create=false \\
--set serviceAccount.name=aws-load-balancer-controller

AWS官方表示,有時候的安全性更新不會這麼快的更新到helm chart上。在用helm chart安裝完後,可以去AWS Github上更新crds。

kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller/crds?ref=master"

建立完AWS Load Balancer Controller後,就該來試試看Ingress是不是能夠真的work。

建立以下Ingress來驗證一下

vim ing.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
rules:
- host: example.com
http:
paths:
- backend:
service:
name: nginx
port:
number: 80
path: /*
pathType: ImplementationSpecific
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
---
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: ClusterIP
selector:
app: nginx
ports:
- port: 80
protocol: TCP
targetPort: 80
$ kubectl apply -f k8s.yaml
ingress.networking.k8s.io/example-ingress created
deployment.apps/nginx created
service/nginx created
$ kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
example-ingress <none> example.com 80 81s

在apply這樣的設定後,很快地就可以在k8s ingress的清單上看到Address。來試打看看吧

$ curl -H 'Host: example.com' xxx.amazonaws.com
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="<http://nginx.org/>">nginx.org</a>.<br/>
Commercial support is available at
<a href="<http://nginx.com/>">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

可以使用curl正常的使用http連線到nginx上。但我們會發現,現在這樣的設定之下。是沒辦法用https進行連線的。如果要讓https也可以正常連線,就必須在ingress上多加兩條annotations。

alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
# 要使用https就必須從AWS Certificate Manager上掛載一個憑證
alb.ingress.kubernetes.io/certificate-arn: <Certificate arn>

加上之後,就可以用https正常發送request過去了。

Troubleshooting

以下紀錄建立過程中撞到的問題

  1. alb.ingress.kubernetes.io/target-type = instance

建立Ingress後,如果describe ing出現

Error: InvalidParameter: 1 validation error(s) found.\\n- minimum field value of 1, CreateTargetGroupInput.Port.

alb.ingress.kubernetes.io/target-type 若是設定為 Instance,Service就必需設定為NodePort,ingress才能夠正常執行。

Reference

  1. annotations清單

https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/guide/ingress/annotations/

  1. Installing the AWS Load Balancer Controller add-on

https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html

--

--

身為DevOps工程師

目前在蓋亞資訊擔任DevOps Consultant。最近才從後端的世界轉成投向DevOps的懷抱,目前專注在Kubernetes, GitLab, DevSecOps的學習中。