[K8s] EKS 환경에서 Istio + ALB 연동하기 (AWS LoadBalaner Controller)

Dragony·2023년 7월 20일
2

AWS

목록 보기
3/4

EKS에서 istio default 설정을 사용한다면 기본적으로 CLB(클래식 로드밸런서)가 설치된다. EKS 환경에서 Istio로 ALB를 사용하고 싶을 경우 어떻게 해야하는지 알아보자.

AWS LoadBalancer Controller 설치 확인

전제 조건은 AWS Load Balancer Controller를 설치해야 하는데, 해당 pod가 AWS API를 사용하여 요청한 대로 Load Balancer를 설치 및 구성해준다.

해당 AWS Load Balancer Controller가 설치되어 있지 않다면 내장 설치된 Controller를 통해 LB를 설치해야 하는데 지원되는 부분도 많지 않고 ALB를 설치할 수 없다. 따라서 필수적으로 설치해주어야 한다.

k get deploy -n kube-system | grep "NAME|load"

설치 되어있지 않으면 아래 과정으로 설치한다.



IAM / ServiceAccount 설정


(1) AWS 로드 밸런서 컨트롤러의 IAM 정책(사용자 대신 AWS API를 호출) 다운로드

curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.7/docs/install/iam_policy.json

(2) 다운로드한 정책을 사용하여 IAM 정책 생성

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

(3) IAM 자격증명 공급자 생성 (AWS 관리 콘솔)

  • EKS 클러스터에서 OpenID Connect 공급자 URL 복사하여 지문/인증서 확인
  • 대상: sts.amazonaws.com

(4) IAM 역할 생성 (AWS 관리 콘솔)

  • Web Identity > 생성한 자격증명 공급자 연결 > 정책 선택(AWSLoadBalancerControllerIAMPolicy) > 역할 이름 입력(awslbcontroller-role) 후 생성
  • 생성한 역할에서 [신뢰 관계] 편집
oidc.eks.ap-northeast-2.amazonaws.com/id/~~~~~~~~~~~:aud /

sts.amazonaws.com.

    ↓↓↓↓↓
oidc.eks.ap-northeast-2.amazonaws.com/id//~~~~~~~~~~~::sub /

system:serviceaccount:kube-system:aws-load-balancer-controller
  • 추가로 권한 > 권한 추가 > 인라인 정책 생성 > ELB > AddTags 권한 추가

(5) K8s ServiceAccount 추가

  • 위에서 생성한 role 사용
$ vi aws-load-balancer-controller-service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/name: aws-load-balancer-controller
  name: aws-load-balancer-controller
  namespace: kube-system
  annotations:
      eks.amazonaws.com/role-arn: arn:aws:iam::~~~~~:role/awslbcontroller-role

$ kubectl apply -f aws-load-balancer-controller-service-account.yaml
serviceaccount/aws-load-balancer-controller created

여기까지의 작업으로 쿠버네티스의 ServiceAccount 는 AWS 의 AmazonEKSLoadBalancerControllerRole 역할을 얻게 되었고, ingress 와 loadbalancer 에 대하여 AWS 에 ALB 와 NLB 를 각각 생성/관리할 수 있게 되었다.


Load Balancer Controller 설치

helm을 사용하여 설치한다.

(1) helm 저장소 확인

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

(2) 컨트롤러 설치

이미지 저장소 속성에서, 서울의 region-code 는 ap-northeast-2, account 는 602401143452 이다.

image.repository=602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/amazon/aws-load-balancer-controller

helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=<cluster Name> \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller \
--set region=ap-northeast-2 \
--set vpcId=<cluster vpc> \
--set image.repository=602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/amazon/aws-load-balancer-controller

LAST DEPLOYED: Mon Jul 17 10:48:14 2023
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
AWS Load Balancer controller installed!

위 명령에서 install 후에 차트 업그레이드(upgrade)시 필요한 TargetGroupBinding 사용자 리소스를 설치한다.

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


Istio 설치 (1.18.0 버전)

(1) istio 다운로드

$ curl -L https://istio.io/downloadIstio | sh -
$ cd istio-1.18.1
$ export PATH=$PWD/bin:$PATH
$ istioctl version
no ready Istio pods in "istio-system"
1.18.0

(2) Operator로 Istio 설치

istioctl install -f istio-operator.yaml
  • istio-operator.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  namespace: istio-system
  name: istiocontrolplane
spec:
  profile: default
  meshConfig:
    enableTracing: true
    defaultConfig: 
      holdApplicationUntilProxyStarts: true
    accessLogFile: /dev/stdout 
    outboundTrafficPolicy:
      mode: REGISTRY_ONLY
  components:
    pilot:
      enabled: true
    egressGateways:
      - name: istio-egressgateway
        enabled: true
    ingressGateways:
      # ALB
      - name: istio-ingressgateway
        enabled: true
        label:
          istio: ingressgateway
        k8s:
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 2000m
              memory: 1024Mi
          hpaSpec:
            minReplicas: 2
            maxReplicas: 4
          serviceAnnotations:  # Health check 관련 정보
            alb.ingress.kubernetes.io/healthcheck-path: /healthz/ready
            alb.ingress.kubernetes.io/healthcheck-port: "30621" # Status Port에서 지정한 nodePort 지정
          service:
            type: NodePort # ingress gateway 의 NodePort 사용
            ports:
              - name: status-port
                protocol: TCP
                port: 15021
                targetPort: 15021
                nodePort: 30621 # 요기!
              - name: http2
                protocol: TCP
                port: 80
                targetPort: 8080
              - name: https
                protocol: TCP
                port: 443
                targetPort: 8443

Ingress 로 ALB 설치

  • Ingress 리소스를 배포하여 ALB를 생성한다.
  • CloudFormation을 사용하지 않았기 때문에 몇가지 수작업으로 진행한다.

subnet 태그 설정

  • 퍼블릭 서브넷은 다음 리소스 태그를 지정한다.
kubernetes.io/role/elb: 1

  • 프라이빗 서브넷은 다음 리소스 태그를 지정한다.
kubernetes.io/role/internal-elb: 1

  • 둘다 공통적으로 다음 리소스 태그를 지정한다.
kubernetes.io/cluster/${your-cluster-name}: owned

Ingress 배포

k apply -f ./istio-ingressgateway-alb.yaml 
  • istio-ingressgateway-alb.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: istio-ingressgateway-alb
  namespace: istio-system
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/certificate-arn: <certification-arn : 도메인에 대한 certification-manager arn >
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
  labels:
    name: istio-ingressgateway-alb
spec:
  ingressClassName: alb
  rules:
  - http:
      paths:
      - pathType: Prefix
        path: /
        backend:
          service:
            name:  istio-ingressgateway
            port: 
              number: 443
profile
안녕하세요 :) 제 개인 공부 정리 블로그입니다. 틀린 내용 수정, 피드백 환영합니다.

1개의 댓글

comment-user-thumbnail
2023년 7월 20일

좋은 글 잘 읽었습니다, 감사합니다.

답글 달기