🧑‍💻 실무 개발 & 시스템

n8n을 AWS EKS를 사용하여 배포하기.( 이해를 위한 정리 글 )

🧑‍💻데브비 2024. 12. 11. 16:11

1. VPC 생성

이유:

EKS 클러스터는 VPC(Virtual Private Cloud) 내에서 동작합니다. VPC는 클러스터와 노드 그룹이 사용할 네트워크 환경을 제공합니다. 이 단계에서는 Kubernetes 워크로드를 위한 네트워크 인프라를 설정합니다.

세부사항:

  • Public VPC의 IPv4 활성화:Public 서브넷을 사용하면 인터넷과 통신해야 하는 애플리케이션과의 연결이 가능합니다. IPv4를 활성화해야 AWS 리소스가 외부 네트워크와 원활히 통신할 수 있습니다.
    • 최소 두 개 이상의 Public 서브넷Private 서브넷을 설정하여 애플리케이션의 보안을 강화합니다.
    • 인터넷 게이트웨이를 연결하여 Public 서브넷에서 인터넷 액세스를 허용합니다.
    • 라우팅 테이블을 적절히 설정합니다.

2. Security Groups

이유:

EKS 클러스터와 노드 그룹이 외부 또는 내부 네트워크와 통신하기 위해서는 보안 규칙(Security Groups)이 필요합니다.

Security Groups는 인바운드 및 아웃바운드 트래픽을 제어합니다.

세부사항:

  • 클러스터용 Security Group:
    • 관리 도구(예: kubectl)에서 접근할 수 있도록 SSH 및 API 서버에 대한 접근을 허용합니다.
  • 노드용 Security Group:
    • 워커 노드 간 통신 및 클러스터와의 통신을 허용합니다.
    • 클러스터 내부에서 사용할 포트(예: 443, 10250, 30000-32767)를 열어야 합니다.

3. Cluster IAM 생성

이유:

EKS 클러스터는 AWS 리소스에 접근할 때 IAM 역할을 필요로 합니다. 클러스터의 관리 및 동작에 필요한 권한을 설정합니다.

세부사항:

  • IAM 역할에 다음 정책을 연결:
    • AmazonEKSClusterPolicy: 클러스터 관리 권한.
    • AmazonEKSVPCResourceController: VPC 관련 리소스를 관리할 권한.

4. Cluster 생성

이유:

EKS 클러스터는 Kubernetes API 서버를 통해 컨테이너화된 애플리케이션을 관리합니다. 이 단계에서 EKS의 핵심 리소스를 생성합니다.

세부사항:

  • EKS 콘솔이나 CLI(eksctl)를 사용하여 클러스터 생성.
  • 생성 시, VPC와 서브넷, 클러스터 IAM 역할을 지정.
  • Kubernetes API 서버가 클러스터 상태와 리소스를 관리하도록 설정.

5. Node IAM 생성

이유:

클러스터의 워커 노드가 EKS와 통신하고 AWS 리소스(예: S3, CloudWatch)에 접근하려면 IAM 역할이 필요합니다.

세부사항:

  • IAM 역할에 다음 정책을 연결:
    • AmazonEKSWorkerNodePolicy: 워커 노드가 클러스터와 통신할 수 있도록 설정.
    • AmazonEC2ContainerRegistryReadOnly: 컨테이너 이미지를 ECR에서 가져올 수 있도록 설정.
    • AmazonEC2RoleforSSM: EC2 인스턴스에 대한 Systems Manager 액세스 제공.

6. Node Group 생성

이유:

Node Group은 Kubernetes 클러스터에서 워크로드를 실행하는 EC2 인스턴스 그룹입니다. 워크로드에 맞는 리소스를 제공하고 클러스터와 연동됩니다.

세부사항:

  • Node Group 생성 시 다음을 지정:
    • 사용 가능한 EC2 인스턴스 유형.
    • 오토스케일링을 위한 최소 및 최대 인스턴스 수.
    • Private 서브넷에 노드를 배치하여 보안을 강화.

7. 도메인 구매

이유:

애플리케이션의 사용자 접근을 위해 고유한 도메인이 필요합니다. Route53을 통해 도메인을 구매하거나 기존 도메인을 사용합니다.

세부사항:

  • Route53에서 도메인을 구매하면 AWS 내부에서 쉽게 관리 가능.

8. 도메인 서브 생성

이유:

도메인 이름의 서브도메인을 설정하여 애플리케이션 또는 서비스에 더 세부적인 네임스페이스를 제공합니다.

세부사항:

  • Route53에서 Hosted Zone을 생성하고 A 레코드 및 CNAME 레코드를 설정합니다.
  • 예: api.example.com, www.example.com.

9. 인증서 발급

이유:

HTTPS를 설정하려면 SSL/TLS 인증서가 필요합니다. AWS Certificate Manager(ACM)를 사용하여 인증서를 생성하면 쉽게 관리할 수 있습니다.

세부사항:

  • ACM에서 인증서를 발급받아 도메인 이름을 HTTPS로 보호.
  • Route53에 도메인 인증(CNAME 레코드 설정)을 수행.

10. HTTPS 생성

이유:

애플리케이션의 보안을 강화하고 사용자 데이터를 암호화하기 위해 HTTPS를 설정합니다.

세부사항:

  • Application Load Balancer(ALB)를 생성하고 ACM 인증서를 연결.
  • ALB 리스너를 통해 HTTP 요청을 HTTPS로 리디렉션 설정.

11. 타겟 그룹 생성

이유:

ALB는 타겟 그룹(Target Group)을 통해 클러스터 내부의 서비스로 트래픽을 라우팅합니다. Kubernetes의 Ingress Controller와 연동하여 애플리케이션 요청을 처리합니다.

세부사항:

  • ALB Target Group을 생성하고 Kubernetes 서비스의 엔드포인트로 설정.
  • Target Group에 적절한 Health Check를 설정하여 가용성을 보장.
[VPC]
  ├── [Internet Gateway] (Public 서브넷이 외부 인터넷과 통신할 수 있도록 연결)
  │
  ├── Public Subnet (외부에 노출)
  │      ├── Application Load Balancer (ALB)
  │      │      ├── 연결: ACM (HTTPS 인증서 연결)
  │      │      ├── 연결: Target Group (트래픽 전달 대상 설정)
  │      │      └── 연결: Route53 (도메인과 ALB의 DNS 이름 매핑)
  │      │
  │      └── 연결: NAT Gateway (Private Subnet 리소스가 외부와 통신 가능하게 설정)
  │
  ├── Private Subnet (보호된 네트워크)
  │      ├── Node Group (EC2 Instances - 워커 노드)
  │      │      ├── 연결: EKS 클러스터 (Kubernetes API Server)
  │      │      │      ├── 연결: Security Group (API 서버 접근 제한)
  │      │      │      └── 연결: IAM Role (AWS 리소스 접근 권한 제공)
  │      │      ├── 연결: Kubernetes API Server (노드 간 통신 및 작업 수행)
  │      │      ├── 연결: Target Group (Kubernetes Service와의 트래픽 라우팅)
  │      │      ├── 연결: Security Group (인바운드/아웃바운드 트래픽 제어)
  │      │      └── 연결: Amazon ECR (컨테이너 이미지 가져오기)
  │
  ├── [Amazon ECR]
  │      ├── 저장: Docker 컨테이너 이미지
  │      └── 연결: Node Group (컨테이너 이미지를 가져와 배포)
  │
  ├── [Route53]
  │      ├── 도메인 (예: www.example.com)
  │      └── 연결: ALB (DNS 이름 매핑)
  │
  ├── [ACM] (HTTPS 보안을 위한 인증서)
  │      └── 연결: ALB (HTTPS 트래픽 암호화)
  │
  └── NAT Gateway
         └── 연결: Private Subnet (인터넷 통신 허용)


  1. Deployment (n8n-deployment)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: n8n-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: n8n
  template:
    metadata:
      labels:
        app: n8n
    spec:
      containers:
      - name: n8n-container
        image: test.dkr.ecr.ap-northeast-2.amazonaws.com/n8n:1.0.1
        ports:
        - containerPort: 5678
      imagePullSecrets:
      - name: ecr-registry-secret

설명

  1. 목적
    • Kubernetes 클러스터 내에서 n8n 컨테이너를 실행하는 Deployment.
    • 2개의 복제본(replicas: 2)으로 컨테이너 인스턴스를 관리하며, 컨테이너가 항상 가용성을 유지.
  2. 이미지 사용
    • 컨테이너 이미지는 Amazon ECR에 저장된 이미지를 사용.
    • test.dkr.ecr.ap-northeast-2.amazonaws.com/n8n:1.0.1 주소에서 이미지를 가져옴.
    • imagePullSecrets은 ECR에서 이미지를 가져올 때 인증 정보를 제공하는 Kubernetes Secret.
  3. 포트 설정
    • 컨테이너가 사용하는 포트는 5678
    • 이 포트는 n8n 컨테이너 내 애플리케이션이 실행되는 포트.

  1. LoadBalancer Service (lb-service)
apiVersion: v1
kind: Service
metadata:
  name: lb-service
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
    service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:ap-northeast-2:test:certificate/
    service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
spec:
  selector:
    app: n8n
  ports:
    - name: http
      port: 80
      targetPort: 5678
    - name: https
      port: 443
      targetPort: 5678
  type: LoadBalancer

설명

  1. AWS Load Balancer 설정
    • *NLB (Network Load Balancer)**을 사용하여 Kubernetes 서비스에 외부 접근성을 제공
    • ALB 대신 NLB을 사용하여 네트워크 레벨 트래픽 라우팅이 가능
  2. SSL 인증서 연결
    • annotations 필드에 ACM 인증서 ARN이 설정되어 있어, HTTPS 트래픽이 SSL 암호화를 통해 처리
    • 이를 통해 데이터 전송 시 보안성을 확보
  3. 포트 매핑
    • 외부에서 접근하는 HTTP(포트 80) 및 HTTPS(포트 443) 요청이 Kubernetes 컨테이너의 targetPort: 5678으로 라우팅
    • 컨테이너 내부에서 실행되는 n8n 앱의 포트와 매핑

  1. Ingress Service (n8n-ingress)
ingressservice.yaml

apiVersion: v1
kind: Service
metadata:
  name: n8n-service
  labels:
    app: n8n
spec:
  ports:
    - port: 80
      targetPort: 5678
      protocol: TCP
  type: ClusterIP
  selector:
    app: n8n
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: n8n-ingress
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-northeast-2:test:certificate
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/ssl-redirect: "443"
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/group.name: n8n-group
  labels:
    app: n8n
spec:
  ingressClassName: alb
  rules:
    - host: test.test.io
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: n8n-service
                port:
                  number: 80

설명

  1. Service (ClusterIP)
    • Kubernetes ClusterIP 서비스는 클러스터 내부에서만 접근할 수 있도록 설정
    • 내부 애플리케이션 컨트롤러가 컨테이너 서비스와 통신
  2. Ingress 컨트롤러 (Application Load Balancer)
    • *AWS ALB (Application Load Balancer)**을 Ingress Controller로 사용
    • Ingress 설정은 ACM 인증서 ARN과 함께 HTTPS 리디렉션 설정으로 구성
    • annotations 필드를 통해 HTTPS 리디렉션 및 SSL 암호화를 활성화
    • Host Rule 설정 (host: test.test.io)을 통해 외부 트래픽 요청을 ALB에서 Kubernetes 서비스로 라우팅합니다.

+-------------------------------------+
|         Kubernetes Cluster          |
+-------------------------------------+
                |
                v
+--------------------------+
|     Deployment           |
| (n8n Deployment)         |
+--------------------------+
        |
        v
+--------------------------+
|         Pods             |
|   (n8n Containers)       |
+--------------------------+
        |
        v
+--------------------------+
|         Service          |
|     (ClusterIP)          |
| Internal communication   |
+--------------------------+
        |
        v
+----------------------------+
|         Service            |
|     (LoadBalancer)         |
|  AWS NLB - External access |
+----------------------------+
        |
        v
+--------------------------+
|         Ingress          |
|      (Application        |
|       Load Balancer)     |
| External HTTPS/HTTP)     |
+--------------------------+
        |
        v
+--------------------------+
|          Route53         |
|  Domain Name Resolution  |
| (test.est.io)            |
+--------------------------+
  • Deployment (n8n Deployment)
    • Kubernetes Deployment은 컨테이너의 배포 및 관리 역할을 함
    • n8n 컨테이너 이미지를 사용하며, 클러스터 내에서 복제본 수(replicas: 2)만큼 Pod을 생성
    • 컨테이너 이미지는 Amazon ECR에서 가져옴
  • Pod 배치
    • Deployment이 생성되면 Kubernetes가 컨트롤 플레인에서 Pod을 생성
    • 각 Pod은 n8n 컨테이너를 실행하며, 컨테이너 내 포트 5678에서 서비스를 제공
  • Service (ClusterIP)
    • Kubernetes Service의 ClusterIP 서비스는 클러스터 내 통신을 위해 사용
    • Service는 Kubernetes 내 Pod 간 통신을 관리하며, 외부 접근이 필요하지 않은 내부 트래픽 처리를 담당
    • Pod에 접근하려면 Service 이름(n8n-service)을 사용
  • Service (LoadBalancer)
    • AWS LoadBalancer Service (NLB)을 통해 외부 접근성을 제공
    • HTTPS 및 HTTP 트래픽은 포트 443과 80에서 전달
    • Service 설정에 연결된 ACM 인증서를 통해 HTTPS 보안 통신이 활성
  • Ingress (Application Load Balancer)
    • Ingress 컨트롤러(ALB)를 사용하여 외부 요청을 Kubernetes Service로 라우팅
    • Ingress 설정이 ACM 인증서를 통해 HTTPS 리디렉션 및 보안 연결을 제공
    • ALB에서 test.test.io 도메인을 Route53과 매핑
  • Route53
    • Route53 DNS 서비스를 통해 도메인 이름(test.test.io)이 ALB에 연결
    • 사용자 요청이 Route53 → ALB → Kubernetes Service 순서로 라우팅되며, 최종적으로 Pod에 도달

 

 

위의 과정을 통해서 EKS를 사용하여 n8n을 띄어보았다.

 

[참고] https://languagestory.tistory.com/281