DEV Community

Thomas Kim
Thomas Kim

Posted on • Edited on

AWS EKS 에서 Istio 와 Application Load Balancer 연결

EKS 에서 Istio 를 설치하면 기본적으로 Classic Load Balancer (CLB) 를 사용하여 설치가 된다. 공식적으로 CLB가 discontinued 된다는 notice는 없지만 CLB는 권장되지 않는다. 결국 L4 Network Load Balancer(NLB) 또는 L7 Application Load Balancer(ALB)로 변경해야 한다. 하지만 AWS WAF 와 같은 서비스를 사용하기 위해서는 반드시 ALB를 사용해야 한다. 여기서는 Istio 와 ALB를 연결해 본다. (NLB를 사용하는 방법은 많이 나와있지만 ALB를 사용하는 방법은 찾기 힘들다...)
https://rtfm.co.ua/en/istio-external-aws-application-loadbalancer-and-istio-ingress-gateway/ 를 참고하였다.

변경되는 Architecture

전체적인 architecture는 이렇게 변경된다. 기존 istio ingress gateway의 service type 은 LoadBalancer 에서 NodePort로 변경하여 기존 CLB가 삭제되고, 대신 Kubernetes 의 Ingress resource를 통해 ALB를 생성한다. 그리고 ALB에서 TLS termination 을 하고 모든 request를 istio ingress gateway pod로 보내고 istio ingress gateway가 application service로 routing 을 하게 된다.


ACM 을 통한 TLS 인증서 설치

첫째, TLS 인증서를 AWS ACM 에 import 한다.
https://docs.aws.amazon.com/acm/latest/userguide/import-certificate-api-cli.html


AWS Load Balancer Controller 설치

ALB를 사용하기 위해서는 AWS Load Balancer Controller가 필요하다. Bastion 서버에서 아래 순서대로 설치를 진행한다.
https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html

IAM Policy 생성

AWS Load Balancer Controller를 위한 IAM Policy를 다운로드한다.

curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.3.1/docs/install/iam_policy.json 
Enter fullscreen mode Exit fullscreen mode

IAM policy를 생성한다.

$ aws iam create-policy \ --policy-name AWSLoadBalancerControllerIAMPolicy \ --policy-document file://iam_policy.json 
Enter fullscreen mode Exit fullscreen mode

IAM Role 및 Kubernetes의 Service Account 생성

위에서 생성된 IAM Policy를 이용하여 아래와 같이 생성한다. 여기서 attach-policy-arn 을 위에서 생성한 policy를 넣는다.

eksctl create iamserviceaccount \ --cluster=eks-demo \ --namespace=kube-system \ --name=aws-load-balancer-controller \ --attach-policy-arn=arn:aws:iam::931639357206:policy/AWSLoadBalancerControllerIAMPolicy \ --override-existing-serviceaccounts \ --approve 
Enter fullscreen mode Exit fullscreen mode

Helm 설치 및 repository 추가

AWS Load Balancer Controller를 Helm을 통해 설치하기 때문에 Helm도 설치하고 eks-charts repository도 추가한다.

$ sudo snap install helm --classic $ helm repo add eks https://aws.github.io/eks-charts $ helm repo update 
Enter fullscreen mode Exit fullscreen mode

AWS Load Balancer Controller 설치

이제 AWS Load Balancer Controller 를 설치한다.

$ helm install aws-load-balancer-controller eks/aws-load-balancer-controller \ -n kube-system \ --set clusterName=eks-demo \ --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 
Enter fullscreen mode Exit fullscreen mode

controller 가 제대로 설치되었는지 확인한다.

kubectl get deployment -n kube-system aws-load-balancer-controller 
Enter fullscreen mode Exit fullscreen mode

Istio 설정 변경

이제 Istio 의 ingress gateway의 service type을 NodePort로 변경하고 ALB가 istio ingreas gateway로 health check 을 할 수 있도록 관련 정보를 넣어준다.

Health check 을 위한 Port number 확인

우선 ALB 가 health check을 위해 사용할 istio ingress gateway 의 health check 관련 nodePort number를 알아본다.

$ kubectl get service istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[?(@.name=="status-port")].nodePort}' 
Enter fullscreen mode Exit fullscreen mode

얻어진 Port number를 아래에서 사용한다.

Istio 설정 업데이트

아래와 같이 istio-operator.yaml 를 업데이트 한다.

apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: namespace: istio-system name: istiocontrolplane spec: profile: default components: egressGateways: - name: istio-egressgateway enabled: true k8s: hpaSpec: minReplicas: 2 ingressGateways: - name: istio-ingressgateway enabled: true k8s: hpaSpec: minReplicas: 2 service: type: NodePort # ingress gateway 의 NodePort 사용 serviceAnnotations: # Health check 관련 정보 alb.ingress.kubernetes.io/healthcheck-path: /healthz/ready alb.ingress.kubernetes.io/healthcheck-port: "32197" # 위에서 얻은 port number를 사용 pilot: enabled: true k8s: hpaSpec: minReplicas: 2 meshConfig: enableTracing: true defaultConfig: holdApplicationUntilProxyStarts: true accessLogFile: /dev/stdout outboundTrafficPolicy: mode: REGISTRY_ONLY 
Enter fullscreen mode Exit fullscreen mode
  • Istio ingress gateway 의 service type을 NodePort로 설정한다.
  • 전 단계에서 얻은 port number를 healthcheck-port 에 넣어 health check 관련 정보를 istio ingress gateway 에 annotation 으로 저장한다.

업데이트된 정보를 Istio 에 적용한다.

$ istioctl install -f istio-operator.yaml 
Enter fullscreen mode Exit fullscreen mode

여기까지 하면 기존 ingress gateway의 service type을 기존 LoadBalancer 에서 NodePort로 변경하였기 때문에 CLB (Classic Load Balancer)는 삭제된다.


ALB 생성

이제 마지막으로 Kubernetes 의 Ingress를 통해 ALB를 생성한다. (AWS Load Balancer Controller는 Kubernetes 의 Ingress 를 통해 ALB 를 생성한다)
아래와 같이 kube-ingress.yaml 파일을 생성한다.

apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-alb namespace: istio-system annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:ap-northeast-2:93163~~~~" alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}' spec: rules: - http: paths: - path: /* backend: serviceName: ssl-redirect servicePort: use-annotation - path: /* backend: serviceName: istio-ingressgateway servicePort: 80 
Enter fullscreen mode Exit fullscreen mode
  • certificate-arn 에는 AWS ACM 에 생성한 TLS certificate의 ARN을 입력한다.

아래와 같이 Ingress를 생성하여 ALB 생성을 완료한다.

$ kubectl apply -f kube-ingress.yaml 
Enter fullscreen mode Exit fullscreen mode

이렇게 기존 CLB를 삭제하고 ALB 로 대체하면서 TLS Termination 은 ALB 에서 일어나고 ALB는 istio-system namespace 에 배포되어 있는 istio-ingressgateway 로 request를 보내게 되고 istio-ingressgateway는 비로서 서비스로 라우팅을 하게 된다.


여기까지 하면 EKS 에 상용에서 사용가능한 Kubernetes Cluster 생성 및 ALB를 통한 TLS Termination, istio ingress gateway의 라우팅이 가능해 진다. 결국 AWS의 WAF 와 같이 ALB가 필수인 서비스를 사용할 수 있다.

Top comments (0)