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
IAM policy를 생성한다.
$ aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam_policy.json
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
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
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
controller 가 제대로 설치되었는지 확인한다.
kubectl get deployment -n kube-system aws-load-balancer-controller
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}'
얻어진 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
- Istio ingress gateway 의 service type을 NodePort로 설정한다.
- 전 단계에서 얻은 port number를 healthcheck-port 에 넣어 health check 관련 정보를 istio ingress gateway 에 annotation 으로 저장한다.
업데이트된 정보를 Istio 에 적용한다.
$ istioctl install -f istio-operator.yaml
여기까지 하면 기존 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
- certificate-arn 에는 AWS ACM 에 생성한 TLS certificate의 ARN을 입력한다.
아래와 같이 Ingress를 생성하여 ALB 생성을 완료한다.
$ kubectl apply -f kube-ingress.yaml
이렇게 기존 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)