인프라 구성 범위
인프라 구성 자동화는 서버가 준비되어 애플리케이션을 배포할 수 있는 상태가 될 때까지의 모든 과정을 다룬다. 크게 세 단계로 나눌 수 있다.
인프라 프로비저닝
서버나 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 | 클라우드 네이티브 방식 | 현대적 인프라 |
| Foreman | Red 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"
}
}
클라우드별 특성 비교
| 항목 | AWS | GCP | Azure |
|---|---|---|---|
| 네트워크 | VPC, Subnet | VPC, Subnet | VNet, Subnet |
| 방화벽 | Security Group | Firewall Rules | NSG |
| 인스턴스 | EC2 | GCE | VM |
| Terraform Provider | hashicorp/aws | hashicorp/google | hashicorp/azurerm |
| 관리형 K8s | EKS | GKE | AKS |
컨테이너 런타임 구성
위의 모든 환경에서 마지막 단계는 컨테이너 런타임을 설치하는 것이다.
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 중심 환경
| 도구 | 언어 | 멀티 클라우드 | 상태 관리 |
|---|---|---|---|
| Terraform | HCL | O | 파일/원격 |
| Pulumi | Python/TS 등 | O | 클라우드 |
| CloudFormation | YAML/JSON | X (AWS) | AWS 관리 |
| Crossplane | YAML (CRD) | O | K8s 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 기반으로, 이벤트 드리븐 아키텍처를 지원한다.
- 장점: 빠른 실행 속도, 이벤트 기반 자동화
- 단점: 복잡한 아키텍처
- 적합한 환경: 대규모 분산 환경
| 도구 | 에이전트 | 언어 | 특징 |
|---|---|---|---|
| Ansible | X | YAML | 간단, SSH 기반 |
| Chef | O | Ruby | 강력한 기능 |
| Puppet | O | 자체 DSL | 선언적 |
| SaltStack | O/X | YAML/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 | 가장 실용적 |
| 베어메탈 (대규모) | MAAS | Ansible | OS 설치 자동화 필요 시 |
| Proxmox | Terraform | Ansible | VM 템플릿 활용 |
| VMware | Terraform | Ansible | vSphere 프로바이더 |
| AWS | Terraform | Ansible/Cloud-init | 관리형 서비스 활용 |
| GCP | Terraform | Ansible/Cloud-init | GKE 고려 |
| Azure | Terraform | Ansible/Cloud-init | AKS 고려 |
규모별 고려사항
소규모 (서버 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편: 서비스 구성 자동화 상세