EKSでaws-load-balancer-controller使ってInternalのALB Ingress Controllerを作成する

PrivateSubnetに構築したEKSにInternalのALBをIngress Controllerとして構築する作業のメモです。 f:id:yomon8:20201114173847p:plain

参考URL

最初に参考にしたURLを張っておきます。

kubernetes-sigs.github.io

github.com

PrivateSubnetへのタグ付け

ALBを配置するサブネットに kubernetes.io/role/internal-elb=1 タグを付けます。EKSクラスタに属しているサブネットから最低でも2つに設定をします。

f:id:yomon8:20201114165505p:plain

EC2ロール作成

参考URLの手順ではIAM Roles for Service Accounts (IRSA)を作成して、IAMとマッピングしていますが。今回はNodeのEC2に紐付いているIAMロールに以下のポリシーを割り当てておきます。(本当はIRSA作成した方が良いので、セキュリティ気になる場合は、その部分は他の記事参考にしてください)

curl -o iam-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/install/iam_policy.json
aws iam create-policy \
    --policy-name AWSLoadBalancerControllerIAMPolicy \
    --policy-document file://iam-policy.json

f:id:yomon8:20201114103929p:plain

CRDの登録

Custom Resource Definitions(CRD)を作成します。

$ kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller//crds?ref=master"
customresourcedefinition.apiextensions.k8s.io/targetgroupbindings.elbv2.k8s.aws created

# 作成されたことを確認
$ kubectl get crd
NAME                                         CREATED AT
# 省略
targetgroupbindings.elbv2.k8s.aws            2020-11-09T23:07:26Z

Helmでaws-load-balancer-controllerをインストール

Helm使ってaws-load-balancer-controllerをインストールします。

まず、EKSのHelmチャートリポジトリのURLを登録します。

helm repo add eks https://aws.github.io/eks-charts

クラスタ名を指定してインストールします。他のパラメータについてはこちらの項目を参照してください。

CLUSTER_NAME=yo-cluster
AWS_REGION=ap-northeast-1
helm upgrade -i aws-load-balancer-controller eks/aws-load-balancer-controller \
  -n kube-system \
 --set image.repository=602401143452.dkr.ecr.${AWS_REGION}.amazonaws.com/amazon/aws-load-balancer-controller \
 --set enableWaf=false \
 --set enableWafv2=false \
 --set syncPeriod=5m \
 --set clusterName=${CLUSTER_NAME}

インストールされたaws-load-balancer-controllerが動いていることを確認します。

$ kubectl get pod -n kube-system 
NAME                                            READY   STATUS    RESTARTS   AGE
aws-load-balancer-controller-7ffbdf5986-ldnn2   1/1     Running   0          11s
# 省略

テストサーバーのデプロイ

参考URLの内容を少しカスタマイズして、InternalのALBに紐付けたechoserverをデプロイしてみます。

kubectl apply -f - <<EOF
---
apiVersion: v1
kind: Namespace
metadata:
  name: echoserver
---
apiVersion: v1
kind: Service
metadata:
  name: echoserver
  namespace: echoserver
spec:
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP
  type: NodePort
  selector:
    app: echoserver
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echoserver
  namespace: echoserver
spec:
  selector:
    matchLabels:
      app: echoserver
  replicas: 1
  template:
    metadata:
      labels:
        app: echoserver
    spec:
      containers:
      - image: gcr.io/google_containers/echoserver:1.4
        imagePullPolicy: Always
        name: echoserver
        ports:
        - containerPort: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: echoserver
  namespace: echoserver
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internal
    alb.ingress.kubernetes.io/tags: Environment=dev,Team=test
spec:
  rules:
    - http:
        paths:
          - path: /
            backend:
              serviceName: echoserver
              servicePort: 80
EOF
namespace/echoserver created
service/echoserver created
deployment.apps/echoserver created
ingress.extensions/echoserver created

ログを見ながらエラー出てないこと確認しつつ待ちます。

kubectl logs -f -nkube-system aws-load-balancer-controller-xxxxxxx

暫くするとALBが作成されます。

f:id:yomon8:20201114141038p:plain

f:id:yomon8:20201114142739p:plain

targetgroupbindingsが作成されているがわかります。

$ kubectl get  -nechoserver targetgroupbindings.elbv2.k8s.aws
NAME                               SERVICE-NAME   SERVICE-PORT   TARGET-TYPE   AGE
k8s-echoserv-echoserv-9c6d225351   echoserver     80             instance      81m

ALBにcurlしてみれば、client_address にリクエスト受けたEKSノードのIPが返ってきます。

$ curl internal-k8s-echoserv-echoserv-xxxxxxxxxx-xxxxxxxxxx.ap-northeast-1.elb.amazonaws.com
CLIENT VALUES:
client_address=xxx.xxx.xxx.xxx
command=GET
real path=/
query=nil
request_version=1.1
request_uri=http://internal-k8s-echoserv-echoserv-xxxxxxxxxx-xxxxxxxxxx.ap-northeast-1.elb.amazonaws.com:8080/
# 省略

掃除

最後に掃除して終わります。

# 数分かかります
$ kubectl delete  -nechoserver ingress.extensions/echoserver
$ kubectl delete  -nechoserver deployment echoserver
$ kubectl delete  -nechoserver service/echoserver

$ kubectl delete namespace echoserver
namespace "echoserver" deleted

$ helm delete aws-load-balancer-controller -n kube-system

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