본문 바로가기

Cloud/AWS

AWS EKS에서 Ingress로 AWS ALB 사용하기

 

Today Keys :  EKS, kubernetes, ingress, alb, application , load balancer, elb, 서비스 

AWS EKS에서 Ingress로 AWS Application Load Balancer(이하 ALB)를 사용 할 수 있습니다.
ALB를 사용함으로써, ALB에서 제공하는 인증서나, WAF와 같은 기능을 사용 할 수 있으며, ALB에 대한 이중화나 용량에 대한 부분을 사용자가 신경 쓰지 않고 사용 않아도 됩니다.  이번 포스팅에서는 AWS EKS에서 ALB를 사용하기 위한 방법과 ALB를 사용한 간단한 서비스를 올리는 테스트를 진행합니다.
 

본 포스팅에서는 AWS EKS 클러스터는 'ZIGI-EKS'라는 이름으로 생성한 상태이고, 서비스 배포를 위한 Node Group까지 구성된 상태에서 진행합니다. 
 
Step 1. 먼저 클러스터의 IAM OIDC 자격 증명 공급자를 생성합니다. Kubernetes 서비스 계정에 IAM 역할을 사용하려면, 클러스터에 IAM OIDC 공급자가 필요합니다. 

 

$ eksctl utils associate-iam-oidc-provider --cluster ZIGI-EKS --approve
 
 
 
AWS EKS 클러스터에서 AWS ALB를 사용하기 위해서는 AWS Load Balancer Controller가 필요합니다.
AWS Load Balancer Controller 통해서 Kubernetes Ingress 생성 시에, AWS ALB를 생성하거나 수정 혹은 삭제를 할 수 있습니다.
 
Step 2. AWS Load Balancer Controller가 AWS API 호출을 허용하는 IAM 정책을 다운로드 받아서, IAM 정책을 생성합니다.
            생성된 정책(Policy)의 Arn 값은 Step 3에서 사용하기 때문에 미리 복사합니다.
$ aws iam create-policy \
    --policy-name AWSLoadBalancerControllerIAMPolicy \
    --policy-document file://iam_policy.json 
 
 
 
Step 3. aws-load-balancer-controller라는 Kubernetes 서비스 계정에 대한 IAM 역할을 생성합니다.
            이 때, Step 2에서 IAM 정책(Policy) 생성 시에 확인된 Arn을 이용하여 역할(Role)에 연결합니다.           
                        https://eksctl.io/usage/iamserviceaccounts/
              

              

$ eksctl create iamserviceaccount \
  --cluster=ZIGI-EKS \
  --namespace=kube-system \
  --name=aws-load-balancer-controller \
  --attach-policy-arn=arn:aws:iam::710278559713:policy/ZIGILBCTRLIAMPolicy \
  --override-existing-serviceaccounts \
  --approve

 ※ 만약, 클러스터의 IAM OIDC 자격 증명 공급자를 생성하는 단계를 진행하지 않았다면, 아래와 같은 오류 메시지가 나옵니다.     Error: unable to create iamserviceaccount(s) without IAM OIDC provider enabled


 
 
Step 4. Helm을 이용해서, AWS Load Balancer Controller을 설치하기 위해 eks-charts Repo를 추가하고, 최신 차트 적용을 위해 업데이트합니다.              
$ helm repo add eks https://aws.github.io/eks-charts
$ helm repo update
 
 
 
Step 5. Helm을 이용해서 AWS Load Balancer Controller을 설치합니다.
            ※ --set region과 --vpcId 값은
                  1.  Amazon EC2 인스턴스 메타데이터 서비스(IMDS)에 대해 제한적인 액세스 권한이 있는 Amazon EC2 노드
                  2.  Fargate
                에 배포 시에 사용하는 flag 입니다.
$ helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
    -n kube-system \
    --set clusterName=ZIGI-EKS \
    --set serviceAccount.create=false \
    --set serviceAccount.name=aws-load-balancer-controller \
    --set image.repository=602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/amazon/aws-load-balancer-controller \
    --set region=ap-northeast-2 \
    --set vpcId=vpc-02f156e28589597c9
                   
 
 
Step 6. 이제 AWS Load Balancer Controller이 잘 설치가 되었는지 확인합니다.         
$ kubectl get deployment -n kube-system aws-load-balancer-controller
 
 
 
 
AWS Load Balancer Controller이 설치가 되었으니, 이제 서비스를 배포하고 이 서비스를 ALB에 연결해서 테스트 해보겠습니다.
 
Step 7. 서비스 테스트를 위한  'zigimario.yaml' 파일을 다음과 같이 작성합니다.   
              
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mario
  labels:
    app: mario
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mario
  template:
    metadata:
      labels:
        app: mario
    spec:
      containers:
      - name: mario
        image: pengbai/docker-supermario
---
apiVersion: v1
kind: Service
metadata:
  name: mario
spec:
  selector:
    app: mario
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
  type: NodePort
 
 
Step 8. 작성한 zigimario.yaml을 이용해서, 배포 후에 정상적으로 Deployment와 Service가 보이는지 확인 합니다.
              
$ kubectl apply -f zigimario.yaml
$ kubectl get deployment -A
$ kubectl get service -A
 
 
 
Step 9. 이제 AWS Load Balancer Controller를 통해서 앞서 만든 서비스를 연결하여 배포하기 위해서 'zigiingress.yaml'을 다음과 같이 작성합니다.
            설정된 Annotations을 간단히 살펴보면,
              ▪ kubernetes.io/ingress.class: alb - Kubernetes Ingress 리소스를 AWS ALB로 사용
              ▪ alb.ingress.kubernetes.io/scheme: internet-facing  internect facing ALB 생성을 위해서 사용. (기본 값은 internal)
              ▪ alb.ingress.kubernetes.io/target-type: ip - 트래픽을 Pod로 라우팅 하는 방법을 지정하는 것으로 ip 지정 시 pod ip로 직접 라우팅 (기본 값은 instance)
              
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: zigiingress
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
spec:
  rules:
    - http:
        paths:
          - pathType: Prefix
            path: /
            backend:
              service:
                name: mario
                port:
                  number: 80
 
 
Step 10-1. 'zigiingress.yaml'을 배포하고, 정상적으로 배포가 되었는지 확인합니다.
              
$ kubectl apply -f zigiingress.yaml
$ kubectl get ingress -A -o wide
 
 
 
Step 10-2. AWS Console에서 보면, Kubectl로 확인한 ingress의 주소를 가진 ALB가 프로비저닝 되고 있는 것을 확인 할 수 있습니다.
 
 
Step 10-3. ALB의 리스너를 확인해 보면, yaml에서 작성한 HTTP(80)이 만들어 진 것을 볼 수 있습니다.
 
Step 10-4. 리스너의 규칙에 들어가 보면, 아래와 같이 Target이 연결 된 것을 볼 수 있습니다.
 
 
Step 11. 이제 ALB가 정상적으로 프로비저닝이 완료되면, ALB의 주소로 접속합니다.
              EKS에 배포된 서비스가 AWS ALB를 이용해 외부에서 정상적으로 연결되는 것을 확인할 수 있습니다.