시스템/배포(Deploy)

[Part4] [1] Terraform을 활용한 AWS EKS 생성

EastHoon 2024. 8. 21. 23:02

1. Terraform을 활용한 AWS EKS 생성 소개

- Terraform은 Infrastructure as Code(IaC)를 위한 도구입니다.

- AWS EKS는 Kubernetes와 완전히 호환되어 쉬운 마이그레이션을 가능하게 합니다.

 

2. 실습 환경 구성을 위한 AWS 네트워크 및 EKS 설계

<순서>

- VPC 생성 (Secondary CIDR 포함)

- Subnet 및 Internet Gateway 생성

- Route Table 생성

- EKS Cluster 생성

- EKS Node Group 생성

- POD (Container) 배포

 

<기본 네트워크 세팅>

- VPC는 기본적으로 하나가 생성되어 있다.

- 두개의 Public Subnet을 사용할 것이다. SubNet은 TAG를 필요로 한다. 클러스터간 통신을 위해서 TAG를 필요로 한다(?)

-  VPC 생성하면 인터넷 게이트웨이(IGW)가 같이 생성된다.

==>

본인의 프로젝트에서는 8개의 서브넷을 생성하였다.

 

 

3. [실습] AWS 웹 콘솔을 활용한 AWS EKS 생성

<순서>

3-1. Security Group 생성

: VPC -> 서브넷 -> IGW -> 보안 그룹 생성 순서!

: 예시) in-bound, out-bound any open으로 생성

 

3-2.  IAM Role 및 Policy 생성

: IAM Role 생성명 test-iam-role-eks-cluster

: Role내 적용할 Policy 목록 - AmazonEKSClusterPolicy - AmazonEKSVPCResourceController

. IAM Role 생성명 test-iam-role-eks-nodegroup

: Role내 적용할 Policy 목록 - AmazonEKSWorkerNodePolicy - AmazonEKS_CNI_Policy - AmazonEC2ContainerRegistryReadOnly

==>

EKS 클러스터와 EKS 노드 그룹을 위한 IAM Role을 각각 생성한다(?)

더보기

{
    "Version": "2012-10-17",
    "Statement": [
        {
        "Effect": "Allow",
        "Principal": {
            "Service": "eks.amazonaws.com"
        },
        "Action": "sts:AssumeRole"
        }
    ]
}

 

{
    "Version": "2012-10-17",
    "Statement": [
        {
        "Effect": "Allow",
        "Principal": {
            "Service": "ec2.amazonaws.com"
        },
        "Action": "sts:AssumeRole"
        }
    ]
}

 

3.3 EKS Cluster 생성

: 약 10 ~ 15분 정도 소요

: 생성시 실패하는 경우는 IAM 설정이 잘 못되어 있거나, 보안그룹 IP 대역이 덜 열여 있거나 하는 경우가 있다.

 

3.4. EKS Node Group 생성

: VPC, 서브넷, 보안그룹 세팅 확인

: 최소, 최대, 원하는 크기로 노드 그룹 설정할 수 있다.

: 자동으로 EC2 생성된다.

 

 

3.5 AWS Configure 및 Kubeconfig 설정

: EKS를 사용하기 위해서는 kubectl를 설치하여야 한다 (리눅스 기준)

1. 파일 다운로드
$ curl -o kubectl https://amazon-eks.s3.us-west-2.amazonaws.com/1.21.2/2021-07-05/bin/linux/amd64/kubectl

2. 권한 적용 및 파일 이동
$ chmod +x ./kubectl && mv ./kubectl /usr/local/bin/

3. kubectl 동작 확인
$ kubectl version

4.AWS 계정 Access Key 설정
$ aws configure

5. Kubectl 사용을 위한 Kubeconfig 설정
$ aws eks update-kubeconfig --region <Region명> --name <EKS명>

==>
~/.kube/config에 설정이 남는다.
클러스터 Endpoint가 config에 존재한다.

 

3.6 POD (Container) 배포

: 컨테이너 POD 배포

1. 예제 코드 > daemonset.yaml 배포
$ kubectl create ‒f daemonset.yaml

2. 예제 코드 > deployment.yaml 배포
$ kubectl create ‒f deployment.yaml

3. 정상 배포 확인
$ kubectl get daemonset
$ kubectl get deployment
$ kubectl get pods(혹은 po)
$ kubectl get pods -A (--all-namespaces)
$ kubeclt get all (pods, svc, demonset, deployment, replicaset 을 전부 보여준다)
$ kubectl desctibe no {노드 이름}

 

 

4. Terraform 소개 (Terraformer 포함)

4.1. Terraform 소개

- https://learn.hashicorp.com/tutorials/terraform/infrastructure-as-code

 

4.2. Terraform 설치 방법

- 설치 방법

(리눅스)
$ curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add ‒
$ sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
$ sudo apt-get update && sudo apt-get install terraform

(윈도우)
1. 다음 URL에서 파일 다운로드
https://releases.hashicorp.com/terraform/1.1.5/terraform_1.1.5_windows_amd64.zip
2. 압축 해제
3. terraform 파일을 실행가능 위치에 두고 실행

 

4.3. Terraform 기본 리소스

(리소스)

- 프로비저닝할 Resource의 오브젝트를 기술

- 각 Resource는 오직 1개의 리소스 타입만 가짐

- Resource내에 사용 가능한 변수를 설정

- 예시 https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_cluster

 

(데이터 소스)

- Provider에서 제공하는 Resource 정보를 가져옴 

- Terraform에서 사용 할 수 있는 형태로 연결 

- Filter를 통해 정보를 가져올 수도 있음 

- 예시 https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/eks_cluster

 

(프로바이더)

- 1000개 이상의 다양한 Provider를 제공

-  Provider를 선언해 해당 인프라에 프로비저닝 할 수 있도록 설정 

- 참고 https://registry.terraform.io/browse/providers

 

(변수)

- Terraform의 tf파일 내에서 사용가능한 변수를 지정

- terraform 명령어가 실행되는 디렉토리 내에 있는 파일에서 사용가능 

- Resource, Data Source, Providers에서 모두 변수 지정해 사용가능

- 참고 https://www.terraform.io/language/values/variable

 

4.4. Terraform 기본 명령어

(프로비저닝)

1. Terraform 초기화

(Init) $ terraform init

2. Terraform 프로비저닝 코드 검증

(Dry Run) $ terraform plan # 추가되는 것을 나타내준다.

3. Terraform 프로비저닝 수행

(Run) $ terraform apply

 

(삭제)

1. Terraform 프로비저닝 적용 삭제 코드 검증

(Dry Run) $ terraform plan --destroy # 삭제 되는 것을 나타내준다.

2. Terraform 프로비저닝 적용 삭제 수행

(Run) $ terraform destroy # 지워지는 것은 생성된 것의 역순이다!

 

5. [실습] Terraform을 활용한 AWS EKS 생성

<사전 준비 사항> - 이건 GUI 기반과 동일하게 먼저 필요하다

1. VPC 생성 및 설정 확인

2. Subnet 생성 확인

3. Internet Gateway 생성 확인

4. Route Table 생성 확인

 

<순서> - AWS GUI 기반과 비교하면서 확인한다!

1. Security Group 생성

security-group.tf

resource "aws_security_group" "test-sg-eks-cluster" {
  name        = "test-sg-eks-cluster"
  description = "security_group for test-eks-cluster"
  vpc_id      = "<VPC ID>"

  tags = {
    Name = "test-sg-eks-cluster"
  }
}

resource "aws_security_group_rule" "test-sg-eks-cluster-ingress" {

  security_group_id = aws_security_group.test-sg-eks-cluster.id
  type              = "ingress" # 들어오는 트레픽
  description       = "ingress security_group_rule for test-eks-cluster"
  from_port         = 0 # 모든 포트
  to_port           = 0  # 모든 포트
  protocol          = "-1" # 모든 프로토콜
  cidr_blocks       = ["0.0.0.0/0"] # NE 오픈??
}

resource "aws_security_group_rule" "test-sg-eks-cluster-egress" {

  security_group_id = aws_security_group.test-sg-eks-cluster.id
  type              = "egress"  # 나가는 트레픽
  description       = "egress security_group_rule for test-eks-cluster"
  from_port         = 0
  to_port           = 0
  protocol          = "-1"
  cidr_blocks       = ["0.0.0.0/0"]
}

 

2. IAM Role 및 Policy 생성

iam-roles.tf

더보기
############ eks cluster iam role ############

resource "aws_iam_role" "test-iam-role-eks-cluster" {
  name = "test-iam-role-eks-cluster"

  assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
    {
    "Effect": "Allow",
    "Principal": {
        "Service": "eks.amazonaws.com"
    },
    "Action": "sts:AssumeRole"
    }
]
}
POLICY
}
# 정책 2개 추가
resource "aws_iam_role_policy_attachment" "test-iam-policy-eks-cluster" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
  role       = aws_iam_role.test-iam-role-eks-cluster.name
}

resource "aws_iam_role_policy_attachment" "test-iam-policy-eks-cluster-vpc" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSVPCResourceController"
  role       = aws_iam_role.test-iam-role-eks-cluster.name
}


############ eks nodegroup iam role ############

resource "aws_iam_role" "test-iam-role-eks-nodegroup" {
  name = "test-iam-role-eks-nodegroup"

  assume_role_policy = <<POLICY
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
POLICY
}
# 정책 3개 추가
resource "aws_iam_role_policy_attachment" "test-iam-policy-eks-nodegroup" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
  role       = aws_iam_role.test-iam-role-eks-nodegroup.name
}

resource "aws_iam_role_policy_attachment" "test-iam-policy-eks-nodegroup-cni" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
  role       = aws_iam_role.test-iam-role-eks-nodegroup.name
}

resource "aws_iam_role_policy_attachment" "test-iam-policy-eks-nodegroup-ecr" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
  role       = aws_iam_role.test-iam-role-eks-nodegroup.name
}

 

3. EKS Cluster 생성

variable.tf

variable "aws_region" {
  default = "ap-northeast-2"
}

variable "cluster-name" {
  default = "test-eks-cluster"
  type    = string
}

 

eks-cluster.tf

resource "aws_eks_cluster" "test-eks-cluster" { # 이름은 test-eks-cluster

  # depends on 은 선 진행되야 하는 것을 명시
  depends_on = [ # "test-iam-role-eks-cluster"  를 depend on 한다.
    aws_iam_role_policy_attachment.test-iam-policy-eks-cluster,
    aws_iam_role_policy_attachment.test-iam-policy-eks-cluster-vpc,
  ]

  name     = var.cluster-name
  role_arn = aws_iam_role.test-iam-role-eks-cluster.arn # eks role을 명시(?)
  version = "1.21"

   # 클러스터의 Control Plane을 AWS 사용자는 볼 수 없는데(블랙박스화) ,
   # 로그는 CloudWatch에서 보게 하기 위해서 아래 처럼 명시한다
  enabled_cluster_log_types = ["api", "audit", "authenticator", "controllerManager", "scheduler"]

  vpc_config {
    security_group_ids = [aws_security_group.test-sg-eks-cluster.id]
    subnet_ids         = ["<Subnet ID 1>","<Subnet ID 2>"] # AWS 서브넷 ID 복사
    endpoint_public_access = true # 인터넷 망에서 EKS Cluster에 퍼블릭 접근하기 위한 것
  }
}

 

providers.tf

terraform {
  required_version = ">= 1.0"
}

provider "aws" {
  region = var.aws_region
}

data "aws_availability_zones" "available" {
  exclude_names = ["ap-northeast-2a","ap-northeast-2c"]
}

 

4. EKS Node Group 생성

eks-nodegroup.tf

resource "aws_eks_node_group" "test-eks-nodegroup" {
  cluster_name    = aws_eks_cluster.test-eks-cluster.name
  node_group_name = "test-eks-nodegroup"
  node_role_arn   = aws_iam_role.test-iam-role-eks-nodegroup.arn
  subnet_ids      = ["<Subnet ID 1>","<Subnet ID 2>"]
  instance_types = ["t3a.medium"]
  disk_size = 20

  labels = {
    "role" = "eks-nodegroup"
  }

  scaling_config {  # worker 노드 갯수 설정 
    desired_size = 2 
    min_size     = 1
    max_size     = 3
  }

  # depends on 은 선 진행되야 하는 것을 명시
  depends_on = [
    aws_iam_role_policy_attachment.test-iam-policy-eks-nodegroup,
    aws_iam_role_policy_attachment.test-iam-policy-eks-nodegroup-cni,
    aws_iam_role_policy_attachment.test-iam-policy-eks-nodegroup-ecr,
  ]

  tags = {
    "Name" = "${aws_eks_cluster.test-eks-cluster.name}-worker-node"
  }
}

 

Q. 설정된 AWS으로 부터 Terraform을 Generation 하는 기능은 존재하는가?

 

5. AWS Configure 및 Kubeconfig 설정

6. POD (Container) 배포

 

6. [실습] Terraformer를 활용한 AWS EKS 관리

- S3 저장소에 terraform state 파일을 저장하는 방법에 대해 다룬다.

 

(현재 급하지 않아서, 나중에 듣는 걸로...)

 

출처: FastCampus/Part4_Kubernetes/Chapter02/Ch02_03-eks at main · DevOpsRunbook/FastCampus (github.com)

 

FastCampus/Part4_Kubernetes/Chapter02/Ch02_03-eks at main · DevOpsRunbook/FastCampus

Kubernetes와 Docker로 한번에 끝내는 컨테이너 기반 MSA 실습 예제코드. Contribute to DevOpsRunbook/FastCampus development by creating an account on GitHub.

github.com

 


Q. 프로비저닝(Provision, 준비)이란?

더보기

프로비저닝(provisioning)은 IT와 네트워크 관리에서 시스템, 서비스, 또는 리소스를 설정하고 준비하는 과정을 의미합니다. 이 과정은 하드웨어, 소프트웨어, 네트워크 인프라 등을 포함하여 다양한 리소스를 사용자에게 제공하거나 시스템을 사용 가능하게 만드는 것을 포함합니다.

주요 프로비저닝 유형:

  1. 하드웨어 프로비저닝 (Hardware Provisioning):
    • 물리적 서버, 스토리지, 네트워크 장비 등을 설치하고 설정하는 과정입니다. 하드웨어가 설치되면 운영 체제와 기본 소프트웨어를 설치하여 사용 준비를 완료합니다.
  2. 소프트웨어 프로비저닝 (Software Provisioning):
    • 운영 체제, 애플리케이션, 데이터베이스 등 소프트웨어를 설치, 구성, 배포하는 과정입니다. 이는 물리적 또는 가상 환경에서 이루어질 수 있습니다.
  3. 네트워크 프로비저닝 (Network Provisioning):
    • 네트워크 장비 및 서비스(예: 스위치, 라우터, 방화벽)를 설정하고 사용자 또는 시스템이 네트워크 리소스에 접근할 수 있도록 설정하는 과정입니다.
  4. 사용자 계정 프로비저닝 (User Account Provisioning):
    • 사용자를 위한 계정을 생성하고, 접근 권한을 설정하며, 필요한 리소스에 대한 접근을 설정하는 과정입니다. 예를 들어, 기업 내에서 신규 직원을 위해 이메일 계정, 파일 서버 접근 권한 등을 설정하는 것이 이에 해당합니다.
  5. 클라우드 프로비저닝 (Cloud Provisioning):
    • 클라우드 서비스에서 가상 머신, 스토리지, 네트워크 리소스를 설정하고 관리하는 과정입니다. 이는 수동으로 또는 자동화된 스크립트를 통해 이루어질 수 있습니다.

프로비저닝의 목적:

프로비저닝은 사용자나 시스템이 필요한 리소스에 신속하게 접근하고 사용할 수 있도록 하는 데 목적이 있습니다. 이는 리소스를 효율적으로 배포하고 관리할 수 있게 하며, IT 인프라의 운영을 원활하게 만드는 중요한 과정입니다.

자동화된 프로비저닝:

현대의 IT 환경에서는 프로비저닝이 자동화된 도구를 통해 이루어지는 경우가 많습니다. 예를 들어, DevOps 환경에서 인프라를 코드로 관리하는 도구(Terraform, Ansible 등)를 사용해 인프라의 프로비저닝을 자동화할 수 있습니다. 이는 인프라 배포 시간을 단축하고, 인적 오류를 줄이며, 일관성을 유지하는 데 도움을 줍니다.

 

==>

- 프로비저닝이란 인프라를 준비한다는 의미이고, 오늘날 IaC (Infra-structure as Code) 를 통해 프로비저닝을 자동화 한다. e.g. 테라폼, 엔서블

- 자동화를 인해 인적 오류를 줄이고, 일관성을 유지한다.

 

Q. 다음은 뭘 뜻하는가? cidr_blocks = ["0.0.0.0/0"]

더보기

`cidr_blocks = ["0.0.0.0/0"]`는 네트워크 설정에서 사용되는 CIDR(클래스리스 도메인 라우팅) 표기법으로, `0.0.0.0/0`은 IPv4 주소 공간 전체를 나타냅니다. 이를 네트워크 정책 또는 방화벽 규칙에서 사용한다면, 해당 규칙이 전 세계의 모든 IP 주소에 대해 적용된다는 것을 의미합니다.

### 구체적으로:
- **`0.0.0.0/0`**:
  - 이 표현은 "모든 IPv4 주소"를 의미합니다.
  - 네트워크 마스크 `/0`은 서브넷 마스크가 0비트라는 의미로, 어떤 부분도 구체적으로 지정되지 않았음을 뜻합니다. 따라서 모든 IPv4 주소(0.0.0.0부터 255.255.255.255까지)가 이 범위에 포함됩니다.

### 일반적인 사용 사례:
- **보안 그룹 또는 방화벽 규칙**: 
  - AWS, GCP, Azure 등의 클라우드 환경에서 보안 그룹이나 네트워크 방화벽을 설정할 때, `0.0.0.0/0`을 사용하면 해당 규칙이 모든 IP 주소에 대해 적용됩니다. 예를 들어, 인바운드 트래픽 규칙에서 `cidr_blocks = ["0.0.0.0/0"]`으로 설정하면, 전 세계에서 해당 포트에 접근이 가능하게 됩니다.

- **VPN 또는 NAT 설정**:
  - `0.0.0.0/0`는 모든 트래픽을 특정 경로(예: VPN을 통해 인터넷으로)를 통해 라우팅해야 함을 나타낼 수 있습니다.

### 주의점:
- **보안 위험**:
  - `0.0.0.0/0`를 설정하면 누구나 해당 리소스에 접근할 수 있으므로, 이를 사용할 때는 매우 신중해야 합니다. 보안 그룹이나 방화벽 규칙에서 이를 사용하면 네트워크 노출이 커지고, 잠재적인 보안 위험이 증가합니다.
  - 일반적으로는 특정 IP 주소나 IP 범위에 대해 접근을 허용하도록 규칙을 더 제한적으로 설정하는 것이 좋습니다.

### 요약:
`cidr_blocks = ["0.0.0.0/0"]`는 "모든 IP 주소"를 뜻하며, 이를 사용하면 해당 규칙이 모든 트래픽에 적용됩니다. 이 설정은 네트워크 리소스에 대해 전 세계적으로 접근을 허용하므로, 보안 측면에서 매우 주의가 필요합니다.

 

반응형