1. Tổng quan.
Proxmox là một hệ thống ảo hóa mã nguồn mở kết hợp giữa ảo hóa máy ảo (VM) và container trên một nền tảng duy nhất. Nó được build trên nền tảng Linux và cung cấp một giải pháp toàn diện để quản lý và triển khai các máy ảo và container. Proxmox cho phép bạn tạo và quản lý các máy ảo (sử dụng KVM – Kernel-based Virtual Machine) cũng như các container (sử dụng LXC – Linux Containers) trên cùng một hệ thống, giúp tối ưu hóa sử dụng tài nguyên và quản lý dễ dàng.
Packer, một công cụ phát triển bởi HashiCorp, là một công cụ hữu ích để build các image hệ thống hoặc máy ảo từ một cơ sở (base image) hoặc từ các file cấu hình, scripts. Packer cho phép bạn tự động hóa quá trình tạo ra các images chuẩn hóa, giúp đảm bảo tính nhất quán trong việc triển khai và quản lý các máy ảo. Packer hỗ trợ nhiều nền tảng ảo hóa, bao gồm cả Proxmox.
Khi bạn muốn build một images hoặc container để triển khai trên Proxmox, bạn có thể sử dụng Packer để xác định cách máy ảo hoặc container sẽ được tạo ra. Bạn có thể định cấu hình các yêu cầu về phần cứng, phần mềm và tài liệu khởi tạo (provisioning) bằng cách sử dụng các file cấu hình. Packer sẽ tạo ra một images sẵn sàng cho việc triển khai lên Proxmox, giúp quá trình triển khai máy ảo hoặc container trở nên nhanh chóng và dễ dàng hơn.
2. Thực hành.
Mình sẽ thực hiện build 1 image Ubuntu 20.04 từ file ISO. Đầu tiên mình tạo các thư mục như dưới.
mkdir -p /home/proxmox/ubuntu-server-focal
mkdir -p /home/proxmox/ubuntu-server-focal/files
mkdir -p /home/proxmox/ubuntu-server-focal/http
File 99-pve.cfg
được sử dụng trong Proxmox Virtual Environment (PVE) để cấu hình hệ thống được cung cấp cho máy ảo (VM) hoặc container khi chúng được triển khai trên PVE.
Trong file cấu hình này, datasource_list
được sử dụng để xác định danh sách các nguồn dữ liệu mà PVE sẽ sử dụng để tìm kiếm thông tin cấu hình khi triển khai máy ảo hoặc container. Hai nguồn dữ liệu thường được sử dụng trong ví dụ của mình là ConfigDrive
và NoCloud
.
- ConfigDrive: ConfigDrive là một phương pháp cung cấp dữ liệu cấu hình cho máy ảo bằng cách sử dụng một ổ đĩa ảo được gắn vào máy ảo. Thông tin cấu hình sẽ được lưu trữ trên ổ đĩa ảo này và máy ảo có thể đọc nó sau khi được triển khai.
- NoCloud: NoCloud là một nguồn dữ liệu được sử dụng khi bạn muốn cung cấp thông tin cấu hình cho máy ảo thông qua dữ liệu được đính kèm trực tiếp vào hình ảnh máy ảo. Thông tin cấu hình thường được cung cấp dưới dạng các file hoặc dữ liệu dạng văn bản.
Dựa trên danh sách “datasource_list”, PVE sẽ cố gắng tìm các nguồn dữ liệu này để trích xuất thông tin cấu hình và áp dụng nó cho máy ảo hoặc container khi chúng được triển khai. Cách cụ thể thông tin này được trích xuất và sử dụng phụ thuộc vào cách bạn đã cấu hình các máy ảo và container của mình.
cat > /Users/hoanghd/Dropbox/proxmox/ubuntu-server-focal/files/99-pve.cfg << OEF
datasource_list: [ConfigDrive, NoCloud]
OEF
File user-data
được sử dụng trong máy ảo (VM) hoặc container khi bạn triển khai chúng trên Proxmox Virtual Environment (PVE). File user-data
thường chứa dữ liệu cấu hình tùy chỉnh cho máy ảo hoặc container.
Cụ thể, file user-data
thường được sử dụng khi bạn muốn cung cấp thông tin cài đặt và cấu hình cho máy ảo hoặc container trong quá trình triển khai. Thông tin trong file user-data
có thể bao gồm các tùy chọn sau:
- Cài đặt hệ điều hành: Bạn có thể cấu hình để máy ảo hoặc container được cài đặt với một phiên bản cụ thể của hệ điều hành. Điều này bao gồm cung cấp tên phiên bản và các thông số khác liên quan đến cài đặt hệ điều hành.
- Cấu hình hệ thống: Bạn có thể đặt thông số về network, port, firewall, hostname, và các thiết lập hệ thống khác dựa trên nhu cầu của bạn.
- Cài đặt ứng dụng và phần mềm: Bạn có thể xác định các gói phần mềm cần được cài đặt và cấu hình trên máy ảo hoặc container.
- Thiết lập người dùng và mật khẩu: Bạn có thể thiết lập tài khoản người dùng và mật khẩu cho máy ảo hoặc container.
- Cấu hình dịch vụ và ứng dụng khác: Bạn có thể đặt các cấu hình tùy chỉnh cho các dịch vụ và ứng dụng cụ thể mà bạn muốn chạy trên máy ảo hoặc container.
Thông qua file user-data
, bạn có thể tự động hóa quá trình cài đặt và cấu hình máy ảo hoặc container, giúp việc triển khai trở nên nhanh chóng và dễ dàng. Thông tin trong file user-data
thường tuân thủ các chuẩn nhất định, như chuẩn cloud-init, để đảm bảo tích hợp trơn tru trong môi trường máy ảo hoặc container
cat > /home/proxmox/ubuntu-server-focal/http/http/user-data << 'OEF'
#cloud-config
autoinstall:
version: 1
locale: en_US
keyboard:
layout: de
ssh:
install-server: true
allow-pw: true
disable_root: false
ssh_quiet_keygen: true
allow_public_ssh_keys: true
packages:
- qemu-guest-agent
- sudo
storage:
layout:
name: direct
swap:
size: 0
user-data:
package_upgrade: false
timezone: Europe/Berlin
chpasswd:
expire: False
users:
- name: hoanghd
groups: [adm, sudo]
lock-passwd: false
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
passwd: hoanghd
- name: root
lock-passwd: false
shell: /bin/bash
passwd: hoanghd
ssh-authorized-keys:
- ssh-rsa <public_key>
OEF
Khi bạn tạo một máy ảo hoặc container trên Proxmox Virtual Environment (PVE) và sử dụng file user-data
để cung cấp dữ liệu cài đặt và cấu hình tùy chỉnh cho máy ảo, file meta-data
có thể bị để trống hoặc chứa thông tin tối thiểu. Lý do chính để file meta-data
thường trống là vì nó thường không chứa nhiều thông tin cấu hình quan trọng.
File meta-data
thường chứa thông tin về kiểu máy ảo hoặc container bạn định triển khai, chẳng hạn như:
- Local-hostname: Tên hostname hoặc domain cho máy ảo.
- InstanceId: Một ID duy nhất để định danh máy ảo.
- Local-ipv4: Địa chỉ IP Local cho máy ảo.
Những thông tin này thường không cần thiết cho việc triển khai cơ bản, và PVE có thể tự động tạo ra các giá trị mặc định nếu bạn không cung cấp build meta-data
hoặc nó trống rỗng.
File meta-data
quan trọng hơn khi bạn sử dụng các dịch vụ cụ thể yêu cầu thông tin từ nó, ví dụ như trong môi trường public cloud hoặc khi bạn muốn tuân thủ chuẩn cụ thể của cloud-init. Nếu bạn không có nhu cầu cụ thể cho các giá trị trong meta-data
, bạn có thể để nó trống và tập trung vào cung cấp thông tin quan trọng hơn trong build user-data
.
touch /home/proxmox/ubuntu-server-focal/http/http/meta-data
File này đơn giản rồi, mình sẽ cung cấp các thông tin kết nối tới Proxmox cho Packer.
cat > /home/proxmox/credentials.pkr.hcl << 'OEF'
proxmox_api_url = "https://192.168.13.225:8006/api2/json" # Your Proxmox IP Address
proxmox_api_token_id = "hoanghd@pam!hoanghd-id" # API Token ID
proxmox_api_token_secret = "61680b60-70b0-412f-a2e7-3737947a6cba"
OEF
Và đây là file quan trọng nhất, nó quyết định bạn sẽ làm gì với Image của bạn. File này là một file cấu hình Packer (ubuntu-server-focal.pkr.hcl
) được sử dụng để build một máy ảo Ubuntu Server (Focal Fossa) trên Proxmox Virtual Environment (PVE).
- Biến (Variables): File cấu hình định nghĩa các biến đã khai báo trong file
credentials.pkr.hcl
ở trên:proxmox_api_url
: URL của Proxmox API.proxmox_api_token_id
: ID của token để truy cập Proxmox API.proxmox_api_token_secret
: Mật khẩu cho token (lưu ý, được đánh dấu là sensitive để giữ bí mật).
- Định nghĩa source definition: Sử dụng
source
để định nghĩa máy ảo (VM) dựa trên ổ đĩa chứa ISO hoặc file ISO trên Proxmox. Các thiết lập bao gồm:- Kết nối Proxmox và thông tin xác thực.
- Thông tin chung về VM như tên, mô tả, vị trí.
- Thiết lập hệ điều hành, bao gồm việc sử dụng một file ISO Local hoặc tải file ISO từ một URL.
- Thiết lập ổ cứng, CPU, bộ nhớ, card mạng, và Cloud-Init settings.
- Chuẩn bị và cài đặt VM (Provisioning):
- Có nhiều bước chuẩn bị và cài đặt VM sau khi máy ảo được triển khai. Các bước này bao gồm:
- Chờ cloud-init hoàn tất quá trình cài đặt.
- Xóa khóa SSH và làm sạch các thông tin liên quan đến VM trước khi triển khai.
- Sao chép file cấu hình từ
99-pve.cfg
vào/etc/cloud/cloud.cfg.d/99-pve.cfg
để cung cấp cài đặt tùy chỉnh cho cloud-init.
- Có nhiều bước chuẩn bị và cài đặt VM sau khi máy ảo được triển khai. Các bước này bao gồm:
- Build: Định nghĩa cụ thể cách build, trong trường hợp này, là build máy ảo Ubuntu Server Focal bằng cách sử dụng source definition được định nghĩa ở trên. Các bước chuẩn bị và cài đặt được xác định ở mục trước được thực hiện trong quá trình build.
File cấu hình này cho phép bạn xác định cách tạo một máy ảo Ubuntu Server Focal trên PVE, bao gồm cả việc định cấu hình hệ thống, cài đặt hệ điều hành, và triển khai các tùy chỉnh thông qua Cloud-Init. Sau khi build cấu hình này đã được định nghĩa, bạn có thể sử dụng Packer để tự động build máy ảo dựa trên nó.
cat > /home/proxmox/ubuntu-server-focal/ubuntu-server-focal.pkr.hcl << 'OEF'
# Ubuntu Server Focal
# ---
# Packer Template to create an Ubuntu Server (Focal) on Proxmox
# Variable Definitions
variable "proxmox_api_url" {
type = string
}
variable "proxmox_api_token_id" {
type = string
}
variable "proxmox_api_token_secret" {
type = string
sensitive = true
}
# Resource Definiation for the VM Template
source "proxmox-iso" "ubuntu-server-focal" {
# Proxmox Connection Settings
proxmox_url = "${var.proxmox_api_url}"
username = "${var.proxmox_api_token_id}"
token = "${var.proxmox_api_token_secret}"
# (Optional) Skip TLS Verification
insecure_skip_tls_verify = true
# VM General Settings
node = "pve-node1"
vm_id = "1990"
vm_name = "ubuntu-server-focal"
template_description = "Ubuntu Server Focal Image"
# VM OS Settings
# (Option 1) Local ISO File
iso_file = "local:iso/ubuntu-20.04.2-live-server-amd64.iso"
# - or -
# (Option 2) Download ISO
# iso_url = "http://old-releases.ubuntu.com/releases/20.04.2/ubuntu-20.04.2-live-server-amd64.iso"
# iso_checksum = "9da66226f3b99849a390a74766d3e578"
iso_storage_pool = "local"
unmount_iso = true
# VM System Settings
qemu_agent = true
# VM Hard Disk Settings
scsi_controller = "virtio-scsi-pci"
disks {
disk_size = "20G"
format = "qcow2"
storage_pool = "ceph-vm"
type = "virtio"
}
# VM CPU Settings
cores = "1"
# VM Memory Settings
memory = "2048"
# VM Network Settings
network_adapters {
model = "virtio"
bridge = "vmbr0"
firewall = "false"
}
# VM Cloud-Init Settings
cloud_init = true
cloud_init_storage_pool = "ceph-vm"
# PACKER Boot Commands
boot_command = [
"<esc><wait><esc><wait>",
"<f6><wait><esc><wait>",
"<bs><bs><bs><bs><bs>",
"ip=${cidrhost("192.168.13.0/24", 198)}::${cidrhost("192.168.12.0/23", 5)}:${cidrnetmask("192.168.12.0/23")}::::${cidrhost("8.8.8.0/24", 8)} autoinstall ds=nocloud-net;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ ",
"--- <enter>"
]
boot = "c"
boot_wait = "5s"
# PACKER Autoinstall Settings
http_directory = "http"
# (Optional) Bind IP Address and Port
http_bind_address = "0.0.0.0"
http_port_min = 8802
http_port_max = 8802
ssh_username = "root"
# (Option 1) Add your Password here
# ssh_password = "hoanghd"
# - or -
# (Option 2) Add your Private SSH KEY file here
ssh_private_key_file = "~/.ssh/id_rsa"
# Raise the timeout, when installation takes longer
ssh_timeout = "24h"
}
# Build Definition to create the VM Template
build {
name = "ubuntu-server-focal"
sources = ["source.proxmox-iso.ubuntu-server-focal"]
# Provisioning the VM Template for Cloud-Init Integration in Proxmox #1
provisioner "shell" {
inline = [
"while [ ! -f /var/lib/cloud/instance/boot-finished ]; do echo 'Waiting for cloud-init...'; sleep 1; done",
"sudo rm /etc/ssh/ssh_host_*",
"sudo truncate -s 0 /etc/machine-id",
"sudo apt -y autoremove --purge",
"sudo apt -y clean",
"sudo apt -y autoclean",
"sudo cloud-init clean",
"sudo rm -f /etc/cloud/cloud.cfg.d/subiquity-disable-cloudinit-networking.cfg",
"sudo sync"
]
}
# Provisioning the VM Template for Cloud-Init Integration in Proxmox #2
provisioner "file" {
source = "files/99-pve.cfg"
destination = "/tmp/99-pve.cfg"
}
# Provisioning the VM Template for Cloud-Init Integration in Proxmox #3
provisioner "shell" {
inline = [ "sudo cp /tmp/99-pve.cfg /etc/cloud/cloud.cfg.d/99-pve.cfg" ]
}
# Add additional provisioning scripts here
# ...
}
OEF
Tại thư mục /home/proxmox/ubuntu-server-focal
hãy chạy lệnh packer validate
để kiểm tra lỗi cú pháp trước khi build. Nếu kết quả trả về The configuration is valid
tức là không có lỗi cú pháp.
$ packer validate --var-file='../credentials.pkr.hcl' ./ubuntu-server-focal.pkr.hcl
The configuration is valid.
Nếu không có lỗi, hãy sử dụng lệnh packer build để bắt đầu build image.
$ packer build --var-file='../credentials.pkr.hcl' ./ubuntu-server-focal.pkr.hcl
ubuntu-server-focal.proxmox-iso.ubuntu-server-focal: output will be in this color.
==> ubuntu-server-focal.proxmox-iso.ubuntu-server-focal: Creating VM
==> ubuntu-server-focal.proxmox-iso.ubuntu-server-focal: Starting VM
==> ubuntu-server-focal.proxmox-iso.ubuntu-server-focal: Starting HTTP server on port 8802
==> ubuntu-server-focal.proxmox-iso.ubuntu-server-focal: Waiting 5s for boot
==> ubuntu-server-focal.proxmox-iso.ubuntu-server-focal: Typing the boot command
==> ubuntu-server-focal.proxmox-iso.ubuntu-server-focal: Waiting for SSH to become available...
Bạn sẽ thấy trên Proxmox sẽ xuất hiện VM/1990 và đang trong quá trình tự động cài đặt.
3. Kết luận.
Bài viết đã giới thiệu về việc sử dụng công cụ Packer để tự động hóa quá trình build máy ảo trên nền tảng Proxmox Virtual Environment.
Chúng ta đã build một file cấu hình Packer dựa trên HCL (HashiCorp Configuration Language). File cấu hình này chỉ các yêu cầu cụ thể cho việc build máy ảo Ubuntu Server Focal, bao gồm thông tin về cài đặt hệ điều hành, cấu hình hệ thống, mạng, và các cài đặt tùy chỉnh.
Khi file cấu hình đã được xác định, quá trình build máy ảo được thực hiện bằng cách sử dụng lệnh packer build
. Quá trình này sử dụng thông tin từ file cấu hình và file biến để tự động build và triển khai máy ảo Ubuntu Server Focal trên PVE.
Trong file cấu hình Packe đã sử dụng đến cách tùy chỉnh máy ảo bằng cách sử dụng Cloud-Init để cung cấp thông tin cài đặt tùy chỉnh sau khi triển khai.
Qua bài viết này chúng ta đã thấy lợi ích của việc sử dụng Packer và Proxmox cho việc tự động hóa việc build image. Nó giúp giảm thời gian và công sức cần thiết cho việc tạo ra các máy ảo chuẩn hóa và có tích hợp sẵn các tùy chỉnh cụ thể.
Cuối cùng, chúng ta đã thảo luận về cơ hội mở rộng và phát triển tiềm năng của dự án, bao gồm việc tùy chỉnh và cải tiến hơn nữa quá trình build image, tích hợp CI/CD và sử dụng các công cụ giám sát và quản lý tài nguyên.
Đề tài này cung cấp một cái nhìn tổng quan về việc tự động hóa việc build máy ảo trên Proxmox bằng cách sử dụng Packer và mô tả các bước để thực hiện quá trình này.