일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 파일시스템
- 커널 파라미터
- backend storage
- vault agent
- SSH OTP
- secret engines
- hashicorp
- 자동화
- 앤서블
- auth methods
- DATA 백업
- SHR
- 시스템
- Role
- devops
- REST API
- IAC
- key/value
- 인프라
- 전체 백업
- Secret Engine
- 유닉스
- 구성관리
- 차분 백업
- kv
- 통합 풀 백업
- 백업
- VIRT
- Vault
- 리눅스
- Today
- Total
클라우드 아카이브
[Infra/IaC] 오픈소스로 살펴보는 Packer 개념과 구성요소 본문
[Infra/IaC] 오픈소스로 살펴보는 Packer 개념과 구성요소
Cloud Engineer 2022. 2. 19. 12:331. 들어가기 전
패커(Packer)는 하시코프(HashiCorp)에서 만든 IaC 도구 중 하나이며, AWS, GCP, Azure를 비롯하여 VMware, Vagrant, OpenStack 등 다양한 플랫폼에서 사용할 수 있는 이미지를 동적으로 사용할 수 있게 해줍니다. 공식 홈페이지(링크)에서는 다양한 플랫폼에서 머신 이미지를 만드는 것을 자동화하는 도구라고 소개합니다.
본 포스팅의 기반 코드는 깃허브에 있는 레퍼지토리(링크)를 기반으로 작성되었습니다. BSD-2 라이센스로 출처를 밝힐 경우 주요 내용 복제, 배포, 수정의 권한 허용 가능하다는 항목을 확인한 이후 포스팅했음을 밝힙니다.
1.1 패커를 사용하는 이유
- 신속한 인프라 구축
- Terraform과 연계하여 몇 초 내에 Packer 이미지를 프로비저닝하여 인스턴스를 시작할 수 있도록 해줍니다.
- Terraform + Ansible + Packer 조합이 자주 사용되며 이를 통해 머신 템플릿 생성부터 인스턴스 프로비저닝까지 신속하게 머신 구성을 할 수 있도록 도와줍니다.
- 다중 공급자 이식성
- 동일한 이미지를 사용하여 AWS, GCP, Azure, VMware 등 다양한 플랫폼에서 환경 별로 인스턴스를 실행할 수 있습니다.
- 어떠한 플랫폼에서든 코드를 기반으로 일관되게 VM/Container 이미지 템플릿을 적용할 수 있게 해줍니다.
2. Packer 구성 요소
2.1 Packer Workflow
2.2 Packer 구성 요소
2.2.1 Packer Block : 본 템플릿에서 사용할 Packer의 구성 정의
Packer 최소 버전과 사용할 플러그인에 대한 정보를 입력합니다.
// linux-rhel.pkr.hcl
// BLOCK: packer
// The Packer configuration.
packer {
required_version = ">= 1.7.10"
required_plugins {
vsphere = {
version = ">= v1.0.3"
source = "github.com/hashicorp/vsphere"
}
}
}
2.2.2 Global Variable : variable 파일에서 변수 바인딩
Packer 템플릿에서 전역 변수를 사용하기 위해 variable에 정의된 변수 이름(2.2.2.1 참고)과 .pkrvar 확장자로 정의된 변수 값(2.2.2.2 참고)을 바인딩해줍니다.
2.2.3 Variable 파일 : 사용할 전역 변수의 명세를 정의
Terraform의 Variable과 유사한 방식이며, 여러 개의 packer 템플릿 파일에서 공유하여 사용할 수 있는 전역 변수(Global Variable)를 정의합니다.
/*
DESCRIPTION:
Red Hat Enterprise Linux 8 variables using the Packer Builder for VMware vSphere (vsphere-iso).
*/
// variables.pkr.hcl
// BLOCK: variable
// Defines the input variables.
// Red Hat Subscription Manager Credentials
variable "rhsm_username" {
type = string
description = "The username to Red Hat Subscription Manager."
sensitive = true
}
variable "rhsm_password" {
type = string
description = "The password to login to Red Hat Subscription Manager."
sensitive = true
}
....
2.2.4 .pkrvars 파일 : 전역 변수에 바인딩할 값을 입력 (Terraform의 Module과 유사)
Terraform의 Module과 유사한 방식이며, variable 파일을 통해 정의한 전역 변수(Global Variable)에 바인딩할 값을 입력합니다.
// vsphere.pkrvars.hcl.example
/*
DESCRIPTION:
VMware vSphere variables used for all builds.
- Variables are use by the source blocks.
*/
// vSphere Credentials
vsphere_endpoint = "sfo-w01-vc01.rainpole.io"
vsphere_username = "svc-packer-vsphere@rainpole.io"
vsphere_password = "R@in!$aG00dThing."
vsphere_insecure_connection = false
....
2.2.5 local 블록에서 로컬 변수를 바인딩
여러 개의 이미지 템플릿 파일에서 공유하는 변수가 아닌, 본 이미지 템플릿에서만 사용할 Local Variable를 정의합니다.
// linux-rhel.pkr.hcl
// BLOCK: locals
// Defines the local variables.
locals {
build_by = "Built by: HashiCorp Packer ${packer.version}"
build_date = formatdate("YYYY-MM-DD hh:mm ZZZ", timestamp())
build_version = formatdate("YY.MM", timestamp())
manifest_date = formatdate("YYYY-MM-DD hh:mm:ss", timestamp())
manifest_path = "${path.cwd}/manifests/"
data_source_content = {
"/ks.cfg" = templatefile("${abspath(path.root)}/data/ks.pkrtpl.hcl", {
build_username = var.build_username
build_password_encrypted = var.build_password_encrypted
rhsm_username = var.rhsm_username
rhsm_password = var.rhsm_password
vm_guest_os_language = var.vm_guest_os_language
vm_guest_os_keyboard = var.vm_guest_os_keyboard
vm_guest_os_timezone = var.vm_guest_os_timezone
})
}
data_source_command = var.common_data_source == "http" ? "inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks.cfg" : "inst.ks=cdrom:/ks.cfg"
}
2.2.6 Source : 이미지로 빌드하기 위한 Base Information을 정의
이미지를 빌드하기 위해 필요한 기본 정보(vCenter Credential, CPU/Memory 등의 리소스 스펙 등)를 정의합니다.
// linux-rhel.pkr.hcl
// BLOCK: source
// Defines the builder configuration blocks.
source "vsphere-iso" "linux-rhel" {
// vCenter Server Endpoint Settings and Credentials
vcenter_server = var.vsphere_endpoint
username = var.vsphere_username
password = var.vsphere_password
insecure_connection = var.vsphere_insecure_connection
// vSphere Settings
datacenter = var.vsphere_datacenter
cluster = var.vsphere_cluster
datastore = var.vsphere_datastore
folder = var.vsphere_folder
// Virtual Machine Settings
guest_os_type = var.vm_guest_os_type
vm_name = "${var.vm_guest_os_family}-${var.vm_guest_os_name}-${var.vm_guest_os_version}-v${local.build_version}"
firmware = var.vm_firmware
CPUs = var.vm_cpu_sockets
cpu_cores = var.vm_cpu_cores
CPU_hot_plug = var.vm_cpu_hot_add
RAM = var.vm_mem_size
RAM_hot_plug = var.vm_mem_hot_add
cdrom_type = var.vm_cdrom_type
disk_controller_type = var.vm_disk_controller_type
storage {
disk_size = var.vm_disk_size
disk_thin_provisioned = var.vm_disk_thin_provisioned
}
network_adapters {
network = var.vsphere_network
network_card = var.vm_network_card
}
vm_version = var.common_vm_version
remove_cdrom = var.common_remove_cdrom
....
2.2.7 Build : Source 정보를 기반으로 이미지에 대한 프로비저닝 수행
Build 블록에서 provisioner 기능을 통해 다양한 구성 방식 및 도구(ansible, shell 등)를 사용하여 이미지에 대한 프로비저닝을 수행할 수 있으며, 본 작업 이후 Post-Process 기능으로 추가로 하고자하는 작업을 정의할 수 있습니다. Post-Process에서는 생성한 이미지에 대한 상세 정보를 기록하는 manifest와 같은 작업을 주로 수행합니다.
// linux-rhel.pkr.hcl
// BLOCK: build
// Defines the builders to run, provisioners, and post-processors.
build {
sources = ["source.vsphere-iso.linux-rhel"]
provisioner "ansible" {
playbook_file = "${path.cwd}/ansible/main.yml"
roles_path = "${path.cwd}/ansible/roles"
ansible_env_vars = [
"ANSIBLE_CONFIG=${path.cwd}/ansible/ansible.cfg"
]
extra_arguments = [
"--extra-vars", "display_skipped_hosts=false",
"--extra-vars", "BUILD_USERNAME=${var.build_username}",
"--extra-vars", "BUILD_SECRET='${var.build_key}'",
"--extra-vars", "ANSIBLE_USERNAME=${var.ansible_username}",
"--extra-vars", "ANSIBLE_SECRET='${var.ansible_key}'",
]
}
post-processor "manifest" {
output = "${local.manifest_path}${local.manifest_date}.json"
strip_path = true
strip_time = true
custom_data = {
ansible_username = var.ansible_username
build_username = var.build_username
build_date = local.build_date
build_version = local.build_version
common_data_source = var.common_data_source
common_vm_version = var.common_vm_version
vm_cpu_cores = var.vm_cpu_cores
vm_cpu_sockets = var.vm_cpu_sockets
vm_disk_size = var.vm_disk_size
vm_disk_thin_provisioned = var.vm_disk_thin_provisioned
vm_firmware = var.vm_firmware
vm_guest_os_type = var.vm_guest_os_type
vm_mem_size = var.vm_mem_size
vm_network_card = var.vm_network_card
vsphere_cluster = var.vsphere_cluster
vsphere_datacenter = var.vsphere_datacenter
vsphere_datastore = var.vsphere_datastore
vsphere_endpoint = var.vsphere_endpoint
vsphere_folder = var.vsphere_folder
vsphere_iso_path = "[${var.common_iso_datastore}] ${var.iso_path}/${var.iso_file}"
}
}
}
마무리
Packer 관련 오픈소스를 기반으로 Packer에 대한 개념과 구성 요소를 알아보는 포스팅을 마무리하겠습니다. 일반적으로 Terraform + Packer + Ansible 조합과 빌드 및 테스트를 위한 CI(Continuous Integration)를 구성하여 DevOps 파이프라인을 구축하기도 합니다. 본 조합은 Private Cloud(vCenter, OpenStack 등) 뿐만 아니라 Public Cloud(AWS, GCP, Azure 등)에서도 구성이 가능합니다. 뛰어난 데브옵스 엔지니어가 되기 위해서는 반드시 알고 있어야 하는 Packer에 대한 포스팅을 마치겠습니다.