이번에는 Kubernetes의 요소 중 하나인 Ingress에 대해서 알아보고 AWS EKS에서는 Ingress를 어떻게 사용하는지에 대해서 알아보도록 하겠다.
먼저 Ingress라는 개념을 알아야 한다. Ingress는 트래픽을 각기 다른 백엔드(서비스)에 매핑을 시켜주는 역할을 한다.
이 때 http, https를 이용하며 복잡한 트래픽을 관리할 수 있게 해준다.
위와 같이 Ingress에 설정한 라우팅 규칙을 통해 서비스로 트래픽을 전달하며 여러 서비스를 묶을 수 있다.
이 때 호스트 기반으로도 라우팅 규칙을 정할 수도 있고 Path 기반으로 라우팅을 정할 수 있다.
퍼블릭 클라우드를 사용한다면 각 클라우드 서비스마다 Ingress Controller를 구현하는 방법이 조금 다른데, AWS 같은 경우는 Application Load Balancer를 통해서 Ingress를 구축할 수 있다.
또 Path 기반의 라우팅은 Target Group을 통해서 설정할 수 있다.
이번 글을 통해서는 독립된 두개의 nginx 서비스를 배포하고 Path based routing을 적용한 Ingress를 구축해볼 예정이다.
먼저 클러스터를 생성한다. 이번 글에서는 loadbalancer-controller, cert manager, nginx services 등 다양한 파드를 실행하므로 t3.small
로 노드 타입을 정해주었다.
eksctl create cluster \
--name ingress-test-cluster \
--nodegroup-name ng-default \
--node-type t3.small \
--nodes 2
Ingress를 구현할 Loadbalancer의 권한을 위해서 oicd를 허용해준다.
# oicd 허용
eksctl utils associate-iam-oidc-provider \
--cluster=ingress-test-cluster \
--approve
# oicd 확인
aws eks describe-cluster --name ingress-test-cluster --query "cluster.identity.oidc.issuer" --output text
# oicd 리스트 확인
aws iam list-open-id-connect-providers
그리고 policy를 만들어준다. policy는 Json 파일 기반으로 만들어주었다.
코드가 조금 기므로 깃허브 링크를 첨부한다.
위 링크에 있는 코드대로 파일을 만들어준 후 policy를 생성해준다.
aws iam create-policy \
--policy-name ALBIngressControllerIAMPolicy \
--policy-document file://ingress/alb-ingress-policy.json
다음으로는 만들어진 policy로 service account를 만들어주면 된다.
# service account 생성
eksctl create iamserviceaccount \
--cluster=ingress-test-cluster \
--namespace=kube-system \
--name=alb-ingress-controller \
--attach-policy-arn=arn:aws:iam::<여러분의_AWS계정_ACCOUNT_ID>:policy/ALBIngressControllerIAMPolicy \
--override-existing-serviceaccounts \
--approve
# service account 확인
kubectl get serviceaccounts -n kube-system alb-ingress-controller -o yaml
이렇게 하면 cluster 설치 및 인증 작업은 끝난다.
위에서 말했듯 AWS는 Ingress Controller를 ALB를 통해 구성할 수 있다.
# helm 리포지토리 설치
helm repo add eks https://aws.github.io/eks-charts
helm repo update
# aws lb controller 설치
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=ingress-test-cluster \
--set serviceAccount.create=false \
--set serviceAccount.name=alb-ingress-controller \
--set region=ap-northeast-2 \
--set vpcId=<여러분의_VPC_ID>
# 설치 확인
kubectl -n kube-system get pods | grep balancer
위 코드를 통해 aws-load-balancer-controller를 설치한다.
여기까지 하면 일단 준비는 끝이다. 이 때 ingress controller가 정상적으로 Service Account를 통해 권한을 잘 획득했는지 확인할 필요가 있다.
# Service Account 확인
kubectl get serviceaccount aws-load-balancer-controller -n kube-system -o yaml
# Service Account에 연결된 IAM role ARN 확인
kubectl describe serviceaccount aws-load-balancer-controller -n kube-system
aws iam list-attached-role-policies --role-name <생성된_ROLE_NAME>
# kubectl get pod -n kube-system
위 명령어를 통해 aws-load-balancer-controller가 정상적으로 권한을 가지고 실행이 잘 되었는지 확인해준다.
두 개의 Deployment, Service, ConfigMap을 포함한 파일을 작성해준다.
역시 코드가 조금 기므로 링크를 첨부한다 Nginx-1, Nginx-2
위 두 코드는 Deployment를 통해서 nginx 파드를 배포하고, Service를 통해 Ingress Controller에서 파드들을 감지할 수 있도록 해준다.
또 추가적으로 ConfigMap 볼륨 마운트를 통해
하도록 설정해주었다.
이제 ingress controller를 alb로 지정했고, nginx의 파드도 만들어주었다. 이제 이 ingress를 어떤 기준으로 라우팅 해줄지 설정하는 Ingress Resource도 만들어줘야 한다.
# nginx-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: "nginx-ingress"
annotations:
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/scheme: internet-facing
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /nginx2
pathType: Prefix
backend:
service:
name: nginx-2
port:
number: 80
- path: /nginx1
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
대략 이런 파일을 작성해주면 된다. ingressClassName을 통해 alb로 라우팅을 하도록 설정하고, 아래 path에 따라서 어떤 서비스로 라우팅을 해줄지 정해줄 수 있다.
kubectl apply -f ingress/nginx-ingress.yaml
위 커맨드를 통해 nginx-ingress를 생성해줄 수 있다.
하지만 ingress controller, ingress resource만 생성해준다고 해서 로드 밸런서가 생성되지는 않는다.
로드 밸런서는 실제로 사용할 파드들이 생성되면 그 때부터 생성이 시작되며 Ingress Resource에서 설정해준 Path는 Application LoadBalancer의 Target Group을 통해서 생성이 된다.
이제 두 개의 다른 nginx 서비스를 실행시켜 주자.
kubectl apply -f ingress/nginx-deploy-1.yaml
kubectl apply -f ingress/nginx-deploy-2.yaml
이렇게 하면 AWS 콘솔에서 로드 밸런서가 프로비저닝되고 <로드밸런서_DNS>/nginx1
과 <로드밸런서_DNS/nginx2
로 접근하면
이렇게 각기 다른 서비스에 배포된 파드들로 라우팅 되는 것을 확인할 수 있다.
정리하자면
이번 Ingress에서 사용한 전체 코드는 여기에서 확인할 수 있다.
참고
인그레스(Ingress)
https://aws.amazon.com/ko/blogs/opensource/kubernetes-ingress-aws-alb-ingress-controller/
[참고][마리오] AWS EKS에서 Ingress로 AWS ALB 사용하기
https://awskocaptain.gitbook.io/aws-builders-eks/6.-aws-load-balancer-controller