인프라 구성 자동화 상세




인프라 구성 범위

인프라 구성 자동화는 서버가 준비되어 애플리케이션을 배포할 수 있는 상태가 될 때까지의 모든 과정을 다룬다. 크게 세 단계로 나눌 수 있다.

인프라 프로비저닝

서버나 VM을 생성하고 기본 네트워크를 구성하는 단계다.

  • 클라우드: VPC, 서브넷, 보안 그룹, EC2/GCE 인스턴스
  • 가상화: VM 생성, 가상 네트워크, 스토리지 할당
  • 베어메탈: 물리 서버 준비 (이 단계는 대부분 수동)

기본 서버 셋팅

OS 설치 후 서버를 운영 가능한 상태로 만드는 단계다.

  • 사용자 및 SSH 키 설정
  • 기본 패키지 설치 (curl, vim, htop 등)
  • 타임존, 로케일 설정
  • 방화벽 및 보안 설정
  • 모니터링 에이전트 설치

런타임 환경 구성

애플리케이션을 실행할 수 있는 환경을 준비하는 단계다.

  • 컨테이너 런타임: Docker, containerd, Podman
  • 오케스트레이션: Kubernetes, k3s, Docker Swarm

환경별 구성 플로우

베어메탈

물리 서버 환경에서는 Terraform 같은 프로비저닝 도구를 사용하기 어렵다. OS 설치 이후부터 자동화를 시작하는 것이 현실적이다.

구성 플로우

물리 서버 준비
    ↓
OS 설치 (수동 또는 PXE/MAAS)
    ↓
Ansible 실행
├── 사용자/SSH 설정
├── 기본 패키지 설치
├── 타임존/로케일 설정
├── 방화벽 설정
├── Docker/containerd 설치
└── k3s 클러스터 구성
    ↓
[인프라 구성 완료]

OS 설치 자동화 옵션

서버가 몇 대 안 되면 수동 설치 후 Ansible로 넘어가는 것이 효율적이다. 서버 수가 많다면 다음 도구를 고려할 수 있다.

도구특징적합한 환경
PXE + Kickstart전통적 방식, 네트워크 부팅대규모 데이터센터
MAAS웹 UI 제공, Ubuntu 친화적중소규모 온프레미스
Tinkerbell클라우드 네이티브 방식현대적 인프라
ForemanRed Hat 계열, 다양한 기능엔터프라이즈

Ansible 인벤토리 예시

# inventory.yml
all:
  children:
    masters:
      hosts:
        minipc-1:
          ansible_host: 192.168.1.10
    workers:
      hosts:
        minipc-2:
          ansible_host: 192.168.1.11
        minipc-3:
          ansible_host: 192.168.1.12
  vars:
    ansible_user: ubuntu
    ansible_ssh_private_key_file: ~/.ssh/id_rsa

가상화 (Proxmox, VMware)

가상화 환경에서는 Terraform으로 VM을 생성하고, Cloud-init으로 초기 설정을 수행한 뒤, Ansible로 상세 구성을 진행한다.

구성 플로우

Terraform 실행
├── VM 생성
├── CPU/메모리/디스크 할당
├── 네트워크 연결
└── Cloud-init 템플릿 지정
    ↓
Cloud-init 실행 (VM 첫 부팅 시)
├── 호스트명 설정
├── 사용자/SSH 키 설정
└── 네트워크 설정 (DHCP/고정IP)
    ↓
Ansible 실행
├── 추가 패키지 설치
├── 보안 설정
├── Docker/containerd 설치
└── k3s 클러스터 구성
    ↓
[인프라 구성 완료]

Terraform Proxmox 예시

# main.tf
terraform {
  required_providers {
    proxmox = {
      source = "bpg/proxmox"
    }
  }
}

resource "proxmox_virtual_environment_vm" "k3s_node" {
  name      = "k3s-node-1"
  node_name = "pve"

  cpu {
    cores = 2
  }

  memory {
    dedicated = 4096
  }

  disk {
    datastore_id = "local-lvm"
    size         = 32
    interface    = "scsi0"
  }

  network_device {
    bridge = "vmbr0"
  }

  initialization {
    user_data_file_id = proxmox_virtual_environment_file.cloud_init.id
  }
}

Cloud-init 설정 예시

#cloud-config
hostname: k3s-node-1
users:
  - name: ubuntu
    sudo: ALL=(ALL) NOPASSWD:ALL
    ssh_authorized_keys:
      - ssh-rsa AAAA...
timezone: Asia/Seoul
package_update: true
packages:
  - curl
  - vim

퍼블릭 클라우드 (AWS, GCP, Azure)

퍼블릭 클라우드에서는 네트워크 인프라부터 서버까지 모든 것을 Terraform으로 프로비저닝할 수 있다.

구성 플로우

Terraform 실행
├── VPC/서브넷 생성
├── 보안 그룹/방화벽 규칙
├── EC2/GCE 인스턴스 생성
└── User-data (Cloud-init) 전달
    ↓
Cloud-init 실행 (인스턴스 첫 부팅 시)
├── 호스트명 설정
├── 사용자/SSH 키 설정
└── 기본 패키지 설치
    ↓
Ansible 실행 (선택적)
├── 추가 구성
├── Docker/containerd 설치
└── k3s 클러스터 구성
    ↓
[인프라 구성 완료]

Terraform AWS 예시

# main.tf
provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
  
  tags = {
    Name = "k3s-vpc"
  }
}

resource "aws_subnet" "public" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.1.0/24"
  map_public_ip_on_launch = true
}

resource "aws_security_group" "k3s" {
  vpc_id = aws_vpc.main.id

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 6443
    to_port     = 6443
    protocol    = "tcp"
    cidr_blocks = ["10.0.0.0/16"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_instance" "k3s_master" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.medium"
  subnet_id     = aws_subnet.public.id
  
  vpc_security_group_ids = [aws_security_group.k3s.id]

  user_data = <<-EOF
    #!/bin/bash
    curl -sfL https://get.k3s.io | sh -
  EOF

  tags = {
    Name = "k3s-master"
  }
}

클라우드별 특성 비교

항목AWSGCPAzure
네트워크VPC, SubnetVPC, SubnetVNet, Subnet
방화벽Security GroupFirewall RulesNSG
인스턴스EC2GCEVM
Terraform Providerhashicorp/awshashicorp/googlehashicorp/azurerm
관리형 K8sEKSGKEAKS

컨테이너 런타임 구성

위의 모든 환경에서 마지막 단계는 컨테이너 런타임을 설치하는 것이다.

Docker 설치 (Ansible)

# roles/docker/tasks/main.yml
- name: Docker GPG 키 추가
  apt_key:
    url: https://download.docker.com/linux/ubuntu/gpg
    state: present

- name: Docker 저장소 추가
  apt_repository:
    repo: deb https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable
    state: present

- name: Docker 설치
  apt:
    name:
      - docker-ce
      - docker-ce-cli
      - containerd.io
    state: present
    update_cache: yes

- name: Docker 서비스 시작
  systemd:
    name: docker
    state: started
    enabled: yes

k3s 클러스터 구성 (Ansible)

# roles/k3s-master/tasks/main.yml
- name: k3s 마스터 설치
  shell: curl -sfL https://get.k3s.io | sh -s - server --cluster-init
  args:
    creates: /etc/rancher/k3s/k3s.yaml

- name: 토큰 파일 읽기
  slurp:
    src: /var/lib/rancher/k3s/server/node-token
  register: k3s_token

# roles/k3s-worker/tasks/main.yml
- name: k3s 워커 설치
  shell: |
    curl -sfL https://get.k3s.io | K3S_URL=https://{{ master_ip }}:6443 K3S_TOKEN={{ k3s_token }} sh -
  args:
    creates: /etc/rancher/k3s/k3s.yaml

주요 도구 상세

프로비저닝 도구

Terraform

HashiCorp에서 개발한 IaC 도구로, 가장 널리 사용된다. HCL(HashiCorp Configuration Language)로 인프라를 정의하고, 다양한 프로바이더를 통해 멀티 클라우드 환경을 지원한다.

  • 장점: 넓은 생태계, 상태 관리, 멀티 클라우드
  • 단점: HCL 학습 필요, 상태 파일 관리 필요
  • 적합한 환경: 클라우드, 가상화 환경

Pulumi

범용 프로그래밍 언어(Python, TypeScript, Go 등)로 인프라를 정의할 수 있다.

  • 장점: 익숙한 언어 사용, 조건문/반복문 자유로움
  • 단점: 상대적으로 작은 생태계
  • 적합한 환경: 개발자 친화적 환경

CloudFormation

AWS 전용 IaC 도구로, AWS 서비스와 네이티브 통합된다.

  • 장점: AWS 완벽 지원, 추가 비용 없음
  • 단점: AWS 전용, YAML/JSON 장황함
  • 적합한 환경: AWS 단일 클라우드

Crossplane

Kubernetes CRD(Custom Resource Definition)로 클라우드 리소스를 관리한다.

  • 장점: K8s 네이티브, GitOps 친화적
  • 단점: K8s 필수, 학습 곡선
  • 적합한 환경: K8s 중심 환경
도구언어멀티 클라우드상태 관리
TerraformHCLO파일/원격
PulumiPython/TS 등O클라우드
CloudFormationYAML/JSONX (AWS)AWS 관리
CrossplaneYAML (CRD)OK8s etcd

OS 설치 자동화 도구

PXE + Kickstart/Preseed

네트워크 부팅(PXE)과 자동 응답 파일을 조합한 전통적인 방식이다. Kickstart는 RHEL 계열, Preseed는 Debian 계열에서 사용한다.

  • 장점: 검증된 방식, 유연한 커스터마이징
  • 단점: 초기 설정 복잡, DHCP/TFTP 서버 필요

MAAS (Metal as a Service)

Canonical에서 개발한 베어메탈 프로비저닝 도구다. 웹 UI와 API를 제공하며, Terraform 프로바이더도 있다.

  • 장점: 웹 UI, API 지원, Ubuntu 친화적
  • 단점: 주로 Ubuntu, 별도 서버 필요

Tinkerbell

Equinix에서 개발한 클라우드 네이티브 베어메탈 프로비저닝 도구다. 컨테이너 기반으로 동작한다.

  • 장점: 현대적 아키텍처, 유연한 워크플로우
  • 단점: 상대적으로 새로운 프로젝트

Foreman

Red Hat 계열에서 많이 사용되는 라이프사이클 관리 도구다. Puppet과 연동이 잘 된다.

  • 장점: 다양한 기능, 엔터프라이즈 지원
  • 단점: 복잡한 설정, Red Hat 편향

구성 관리 도구

Ansible

에이전트 없이 SSH로 동작하는 구성 관리 도구다. YAML로 플레이북을 작성하며, 진입 장벽이 낮다.

  • 장점: 에이전트리스, 쉬운 문법, 넓은 생태계
  • 단점: 대규모에서 느릴 수 있음
  • 적합한 환경: 범용, 특히 베어메탈

Chef

Ruby DSL로 레시피를 작성하며, 에이전트 기반으로 동작한다.

  • 장점: 강력한 기능, 테스트 프레임워크
  • 단점: Ruby 필요, 학습 곡선
  • 적합한 환경: 대규모 엔터프라이즈

Puppet

선언적 언어로 매니페스트를 작성하며, 에이전트 기반으로 동작한다.

  • 장점: 성숙한 생태계, 강력한 리포팅
  • 단점: 자체 DSL 학습 필요
  • 적합한 환경: 대규모 엔터프라이즈

SaltStack

Python 기반으로, 이벤트 드리븐 아키텍처를 지원한다.

  • 장점: 빠른 실행 속도, 이벤트 기반 자동화
  • 단점: 복잡한 아키텍처
  • 적합한 환경: 대규모 분산 환경
도구에이전트언어특징
AnsibleXYAML간단, SSH 기반
ChefORuby강력한 기능
PuppetO자체 DSL선언적
SaltStackO/XYAML/Python빠름, 이벤트 기반

초기 설정 도구

Cloud-init

클라우드 인스턴스의 초기 설정을 자동화하는 표준 도구다. 대부분의 클라우드 이미지에 기본 포함되어 있다.

지원 기능:

  • 호스트명 설정
  • 사용자/그룹 생성
  • SSH 키 설정
  • 패키지 설치
  • 파일 생성
  • 명령어 실행
#cloud-config
hostname: web-server
users:
  - name: admin
    groups: sudo
    shell: /bin/bash
    sudo: ALL=(ALL) NOPASSWD:ALL
    ssh_authorized_keys:
      - ssh-rsa AAAA...
packages:
  - nginx
  - curl
runcmd:
  - systemctl enable nginx
  - systemctl start nginx

Ignition

CoreOS/Flatcar Linux에서 사용하는 초기 설정 도구다. JSON 형식으로 설정을 정의한다.

  • 장점: 빠른 실행, 검증 기능
  • 단점: CoreOS/Flatcar 전용

도구 선택 가이드

환경별 추천 조합

환경프로비저닝구성 관리비고
베어메탈 (소규모)수동Ansible가장 실용적
베어메탈 (대규모)MAASAnsibleOS 설치 자동화 필요 시
ProxmoxTerraformAnsibleVM 템플릿 활용
VMwareTerraformAnsiblevSphere 프로바이더
AWSTerraformAnsible/Cloud-init관리형 서비스 활용
GCPTerraformAnsible/Cloud-initGKE 고려
AzureTerraformAnsible/Cloud-initAKS 고려

규모별 고려사항

소규모 (서버 1~10대)

  • 복잡한 도구보다 Ansible 하나로 충분
  • Terraform은 클라우드/가상화 환경에서만
  • GitOps는 선택적

중규모 (서버 10~100대)

  • Terraform + Ansible 조합 권장
  • 역할(Role) 분리로 재사용성 확보
  • CI/CD 파이프라인 도입 고려

대규모 (서버 100대 이상)

  • 전문 도구 도입 (Puppet, Chef)
  • 상태 관리 중앙화
  • 모니터링/로깅 필수

실전 예시

베어메탈 k3s 클러스터 구성 (Ansible)

디렉토리 구조

ansible/
├── inventory.yml
├── site.yml
├── group_vars/
│   └── all.yml
└── roles/
    ├── common/
    │   └── tasks/main.yml
    ├── k3s-master/
    │   └── tasks/main.yml
    └── k3s-worker/
        └── tasks/main.yml

site.yml

---
- name: 공통 설정
  hosts: all
  become: yes
  roles:
    - common

- name: k3s 마스터 설정
  hosts: masters
  become: yes
  roles:
    - k3s-master

- name: k3s 워커 설정
  hosts: workers
  become: yes
  roles:
    - k3s-worker

roles/common/tasks/main.yml

---
- name: 패키지 업데이트
  apt:
    update_cache: yes
    cache_valid_time: 3600

- name: 기본 패키지 설치
  apt:
    name:
      - curl
      - vim
      - htop
      - net-tools
    state: present

- name: 타임존 설정
  timezone:
    name: Asia/Seoul

- name: 스왑 비활성화
  command: swapoff -a
  when: ansible_swaptotal_mb > 0

- name: 스왑 영구 비활성화
  lineinfile:
    path: /etc/fstab
    regexp: '^.*swap.*$'
    state: absent

실행 명령

ansible-playbook -i inventory.yml site.yml

Proxmox VM 자동 생성 (Terraform)

main.tf

terraform {
  required_providers {
    proxmox = {
      source  = "bpg/proxmox"
      version = ">=0.38.0"
    }
  }
}

provider "proxmox" {
  endpoint = "https://proxmox.local:8006/api2/json"
  username = "root@pam"
  password = var.proxmox_password
  insecure = true
}

variable "proxmox_password" {
  type      = string
  sensitive = true
}

variable "vm_count" {
  default = 3
}

resource "proxmox_virtual_environment_vm" "k3s_node" {
  count     = var.vm_count
  name      = "k3s-node-${count.index + 1}"
  node_name = "pve"

  clone {
    vm_id = 9000  # Ubuntu 템플릿 ID
  }

  cpu {
    cores = 2
  }

  memory {
    dedicated = 4096
  }

  network_device {
    bridge = "vmbr0"
  }

  initialization {
    ip_config {
      ipv4 {
        address = "192.168.1.${10 + count.index}/24"
        gateway = "192.168.1.1"
      }
    }
    user_account {
      username = "ubuntu"
      keys     = [file("~/.ssh/id_rsa.pub")]
    }
  }
}

output "vm_ips" {
  value = [for vm in proxmox_virtual_environment_vm.k3s_node : vm.initialization[0].ip_config[0].ipv4[0].address]
}

실행 명령

terraform init
terraform plan
terraform apply

마무리

이번 글에서는 인프라 구성 자동화를 환경별로 상세하게 살펴봤다.

핵심 내용을 정리하면:

  • 베어메탈: Ansible 중심, OS 설치는 수동 또는 PXE/MAAS
  • 가상화: Terraform으로 VM 생성, Cloud-init + Ansible로 구성
  • 클라우드: Terraform으로 전체 인프라 프로비저닝
  • 런타임: 모든 환경에서 Ansible로 Docker/K8s 설치

다음 글에서는 인프라 위에서 실제 서비스를 배포하고 운영하는 서비스 구성 자동화를 다룬다.


시리즈 목차

  • 1편: 인프라 및 서비스 구성 자동화 개요
  • 2편: 인프라 구성 자동화 상세 (현재 글)
  • 3편: 서비스 구성 자동화 상세



댓글 남기기