๐งฑ Proxmox VE ่ๆฌๆฉ่ชๅๅ็ฎก็:CLI、API ่ Ansible ๆดๅๆ็จ
Proxmox VE ๆๆๅฎๆด็ CLI ๆไปค้、REST API ่ Ansible ๆฏๆด,่ฝไปฅ็จๅผๅๆนๅผๅปบ็ซ VM/LXC、ๆนๆฌก่ชฟๆด่ณๆบ、้ฒ็ซฏๅๅงๅ(Cloud-Init)่็ๅฝๅจๆ็ฎก็。ๆฌๆๆไพๅฏ็ดๆฅ่ค่ฃฝ็่ ณๆฌ่ Playbook,ๅๅฉไฝ ๆๆฅๅธธๆไฝ่ชๅๅ。
ไธ、CLI(qm / pct / pvesh):ๆๅฟซไธๆ็่ชๅๅๅ ฅๅฃ
CLI ้ฉๅๅจๅฎ้ปๆ Pipeline ่ฃกๅฟซ้ๆนๆฌกไฝๆฅญ;ๆญ้ shell ่ฟดๅๅณๅฏ้็ข VM/LXC。
1) ๅปบ็ซ KVM ่ๆฌๆฉ(qm + Cloud-Init)
# ๅๆธ
VMID=101
ISO=local:iso/debian-12.6.0-amd64-netinst.iso
STOR=local-lvm
# ๅปบ็ซ VM ่ๅบๆฌ็กฌ้ซ
qm create $VMID --name "vm-$VMID" --memory 4096 --cores 2 --cpu host \
--net0 virtio,bridge=vmbr0 --scsihw virtio-scsi-pci
# ๅฏๅ
ฅ(ๆ็ดๆฅๆ)็ฃ็ข
qm set $VMID --ide2 $ISO,media=cdrom
qm set $VMID --scsi0 $STOR:32 # 32G ่ๆฌ็ข
# ๅ็จ Cloud-Init(่ชๅๅๅธณ่/็ถฒ่ทฏ/SSH Key)
qm set $VMID --ide0 $STOR:cloudinit
qm set $VMID --ciuser admin --cipassword 'P@ssw0rd!'
qm set $VMID --sshkey ~/.ssh/id_rsa.pub
qm set $VMID --ipconfig0 ip=dhcp
# ้ๆฉ
qm start $VMID
2) ๅปบ็ซ LXC ๅฎนๅจ(pct)
# ไธ่ผ็ฏไพๆจกๆฟ(ๅฏ็จ Web UI ๆ pveam)
pveam available | grep debian-12
pveam download local debian-12-standard_12.2-1_amd64.tar.zst
# ๅปบ็ซๅฎนๅจ
CTID=201
pct create $CTID local:vztmpl/debian-12-standard_12.2-1_amd64.tar.zst \
--hostname lxc-$CTID --cores 2 --memory 2048 --swap 512 \
--rootfs local-lvm:8 --net0 name=eth0,bridge=vmbr0,ip=dhcp --unprivileged 1
pct start $CTID
3) pvesh:ไปฅๆฌๆฉๆไปคๅผๅซ REST API
# ๅๅบๅข้่ณๆบ(็ญๅ GET /api2/json/cluster/resources)
pvesh get /cluster/resources
# ๅปบ็ซๆ็จๅไปฝ(็ญๅ POST /api2/json/nodes/{node}/vzdump)
pvesh create /nodes/node1/vzdump --all 1 --mode snapshot --compress zstd --storage local
ไบ、REST API:่ CI/CD、ๅ ง้จ็ณป็ตฑๅฐๆฅ
Proxmox API ๅ
ฅๅฃ็บ https://<host>:8006/api2/json。ๅปบ่ญฐไฝฟ็จ API Token(้ฟๅ
ๆๆๅฏ็ขผ)。
1) ๅๅพ Token(Web ไป้ข)
- Datacenter → Permissions → API Tokens → ็บ
user@pamๅปบ็ซtokenid,ๅพ้ธ Privilege Separation,ๆๆดพ็ธๅฐๆ่ง่ฒ(ไพๅฆ PVEVMAdmin)。
2) ไฝฟ็จ Token ๅผๅซ API(cURL ็ฏไพ)
# ๅๅบ็ฏ้ป
curl -k -H "Authorization: PVEAPIToken=user@pam!tokenid=SECRET" \
https://pve-1:8006/api2/json/nodes
# ๅปบ็ซ VM(ๅ
็คบๆ,ๅธธ็จๅๆธๅๆฑบๆผๅฒๅญ/็ถฒ่ทฏ)
curl -k -X POST -H "Authorization: PVEAPIToken=user@pam!tokenid=SECRET" \
-d "vmid=150&name=auto-150&memory=4096&cores=2&net0=virtio,bridge=vmbr0" \
https://pve-1:8006/api2/json/nodes/pve-1/qemu
3) ไปฅ Cookie + CSRF(ๅณ็ตฑๆนๅผ)
# ็ปๅ
ฅๅๅพ Ticket ่ CSRF
curl -k -d "username=root@pam&password=YOURPASS" https://pve-1:8006/api2/json/access/ticket
# ไนๅพ POST ้ๅธถไธ:
# -H "CSRFPreventionToken: <from-login>"
# --cookie "PVEAuthCookie=<from-login>"
ไธ、Ansible:ๅฎฃๅๅผๅคง้ไฝๅปบ่ๆถๆ
้ฉๅๆ「ๅปบ็ซ VM → ่จญๅฎ่ฆๆ ผ → ๅๅ → ๅฎ่ฃๅพ่จญๅฎ」ๆต็จๅ,ๆนไพฟ้่คๅท่ก่่ฟฝ่นค。
1) ๅปบ่ญฐ็ฎ้
inventories/
production/
hosts.ini
group_vars/proxmox.yml
playbooks/
create_vms.yml
roles/
postconfig/...
2) inventory(hosts.ini)
[proxmox]
pve-1 ansible_host=10.10.10.11
pve-2 ansible_host=10.10.10.12
[proxmox:vars]
ansible_user=root
ansible_ssh_common_args='-o StrictHostKeyChecking=no'
3) API ้ฃ็ทๅๆธ(group_vars/proxmox.yml)
pve_api_host: "https://10.10.10.11:8006/api2/json"
pve_api_user: "user@pam"
pve_api_token_id: "tokenid"
pve_api_token_secret: "SECRET"
pve_validate_certs: false
4) Playbook(ไฝฟ็จ community.general.proxmox_kvm)
---
- name: Create KVMs on Proxmox
hosts: proxmox
gather_facts: false
collections:
- community.general
vars:
vm_plan:
- { vmid: 310, name: "web-01", memory: 4096, cores: 2 }
- { vmid: 311, name: "web-02", memory: 4096, cores: 2 }
tasks:
- name: Create/ensure VMs
community.general.proxmox_kvm:
api_user: "{{ pve_api_user }}"
api_token_id: "{{ pve_api_token_id }}"
api_token_secret: "{{ pve_api_token_secret }}"
api_host: "{{ pve_api_host }}"
validate_certs: "{{ pve_validate_certs }}"
node: "pve-1"
vmid: "{{ item.vmid }}"
name: "{{ item.name }}"
memory: "{{ item.memory }}"
cores: "{{ item.cores }}"
net:
- model=virtio,bridge=vmbr0
scsihw: virtio-scsi-pci
scsi:
- storage=local-lvm,size=32
state: present
loop: "{{ vm_plan }}"
- name: Start VMs
community.general.proxmox_kvm:
api_user: "{{ pve_api_user }}"
api_token_id: "{{ pve_api_token_id }}"
api_token_secret: "{{ pve_api_token_secret }}"
api_host: "{{ pve_api_host }}"
validate_certs: "{{ pve_validate_certs }}"
node: "pve-1"
vmid: "{{ item.vmid }}"
state: started
loop: "{{ vm_plan }}"
๐ก ่ฅๆฒๆ proxmox_kvm ๆจก็ตๆ้บผ่พฆ?(็จ uri ็ดๆ REST API)
- name: Create VM via REST
uri:
url: "{{ pve_api_host }}/nodes/pve-1/qemu"
method: POST
headers:
Authorization: "PVEAPIToken={{ pve_api_user }}!{{ pve_api_token_id }}={{ pve_api_token_secret }}"
body_format: form-urlencoded
body:
vmid: "320"
name: "api-320"
memory: "4096"
cores: "2"
net0: "virtio,bridge=vmbr0"
validate_certs: false
status_code: 200, 202
ๅ、ๆนๆฌกๅ:ไธ้ตๅคง้ไฝ็ฝฒๅฐ็ฏไพ
#!/usr/bin/env bash
# create_many.sh
for i in {401..405}; do
qm create $i --name "batch-$i" --memory 2048 --cores 2 \
--net0 virtio,bridge=vmbr0 --scsihw virtio-scsi-pci
qm set $i --scsi0 local-lvm:16 --ide2 local:iso/debian-12.iso,media=cdrom
qm start $i
done
ไบ、ๅธธ่ฆ่ชๅๅๆ ๅข
- ๐ ๅพๆจกๆฟๅฟซ้่ค่ฃฝ:ๅ
ๆ Golden Image ่จญ็บๆจกๆฟ
qm template <VMID>,ๅqm cloneๆญ้ Cloud-Init ๆนๆฌก็ๆ。 - ๐ ๆปพๅๆดๆฐ:็จ Ansible ๅฐ VM ๅ็ต,้ๅฐ้ท็งป(ๆๅๆญข)、ๆดๆฐ、้ฉ่ญ,ๅๅๅ HA。
- ๐งฐ ่ณๆบๅฝๆง่ชฟๆด:ไปฅ API/Ansible ไพๅฐๅณฐ่ชๅ่ชฟๆด vCPU/Memory,ไฝ่ฐทๅ็ธฎๅ。
- ๐ก️ ๅไปฝ่ๅฅๅบทๆชขๆฅ:ไปฅ
pvesh่งธ็ผ vzdump,ๆฅ่ชไธฒๆฅ Rsyslog/GoAccess,็ฐๅธธๆ็ผ Slack/Webhook。
ๅ ญ、ๆ้ฏ่ๆไฝณๅฏฆๅ
- API 403:็ขบ่ช Token ่ง่ฒ(Role)ๆฏๅฆๆถต่
VM.Allocate/Sys.Modify็ญๆฌ้。 - ๆจก็ต็ผบๅฐ:Ansible ๅ ่ฃ
ansible-galaxy collection install community.general。 - Cloud-Init ็กๆ:ๆชขๆฅ
--ide0 <storage>:cloudinitๆฏๅฆๅทฒ่จญๅฎ、VM BIOS/Boot ้ ๅบ。 - REST 202:ไปฃ่กจๅทฒๅ็้ๅๆญฅๅทฅไฝ,ๅพ็บๅฏ่ผช่ฉข
/nodes/<node>/tasks/<upid>/status。
๐ ็ต่ช
ๆ CLI、REST API ่ Ansible ไธฒ่ตทไพ,ไฝ ๅฐฑๆๆ「ๅฏ้็พ、ๅฏ่ฟฝ่นค、ๅฏๅๆปพ」็ VM/LXC ็ๅฝๅจๆ็ฎก็。ๅปบ่ญฐ้ ๅๅๆ็็ถฒ่ทฏ/VLAN、ๅฒๅญ、ๅไปฝ、HA ๅข้ๆ็ซ ,ๅฝขๆๅฎๆด็ Proxmox ่ชๅๅไฝๆฅญ้。
๐ ๅปถไผธ้ฑ่ฎ
- ๐งฑ Proxmox VE ้ซๅฏ็จๅข้(HA Cluster)ๆถๆงๅฏฆไฝๆๅ
- ๐งฑ Proxmox VE ๅฟซ็ ง่ๅไปฝ้ๅ:pve-zsync ่ vzdump ่ชๅๅ็ญ็ฅ
- ๐งฑ Proxmox VE ๅฒๅญๆดๅๆๅญธ:ZFS、NFS、iSCSI ่ LVM ็ๅทฎ็ฐ่ๅฏฆไฝ
- ๐งฑ Proxmox VE ็ถฒ่ทฏ่จญๅฎ่ VLAN ็ฎก็:bridge、bonding、VLAN Tag ๅ จ่งฃๆ
— WWFandy・็ณป็ตฑ่็ถฒ่ทฏ็ญ่จ
ๆฒๆ็่จ:
ๅผต่ฒผ็่จ