KVM viết tắt của Kernel Virtualization Machine, được giới thiệu là công nghệ ảo hóa phần cứng. Điều này có nghĩa là hệ điều hành chính OS mô phỏng phần cứng cho các OS khác để chạy trên đó. Ảo hóa KVM có cách hoạt động giống như người quản lý, chia sẻ các nguồn tài nguyên ổ đĩa, network, CPU một cách công bằng. Công nghệ ảo hóa KVM nguồn mở được tích hợp trong Linux.
I. KVM là gì?
- Công nghệ ảo hóa KVM cho phép bạn có thể chuyển Linux thành ảo hóa để máy chủ chạy trên nhiều môi trường ảo bị cô lập gọi là máy khách hoặc máy ảo VM.
- KVM là một phần của mã Linux, nó được hưởng lợi từ các tính năng, KVM sẽ được hưởng lợi từ mọi tính năng, khả năng sửa lỗi, tiến bộ cập nhật mới của Linux mà không cần kỹ thuật bổ sung.
- Ảo hóa KVM không có tài nguyên dùng chung, chúng đã được mặc định sẵn và chia sẻ. Như vậy RAM của mỗi KVM được định sẵn cho từng gói VPS, tận dùng triệt để 100% và không bị chia sẻ. Điều này sẽ giúp cho chúng hoạt động được ổn định hơn, không bị ảnh hưởng bởi các VPS khác chung hệ thống. Tương tự, tài nguyên của ổ cứng cũng được định sẵn phân chia như RAM.
II. Tính năng của công nghệ KVM.
- Tính năng bảo mật: Công nghệ KVM kết hợp với Linux giúp tăng khả năng bảo mật SELinux (xây dựng ranh giới bảo mật quanh máy ảo), sVirt (đẩy mạnh khả năng của SELinux, tăng bảo mật Kiểm soát truy cập bắt buộc MAC dùng cho máy ảo khách, chống lỗi ghi nhãn thủ công, cách ly VM.
- Lưu trữ: KVM cho phép người dùng sử dụng các bộ lưu trữ được Linux hỗ trợ như: bộ lưu trữ gắn mạng NAS, địa cục bộ,… Bạn cũng có thể chia sẻ file để hình ảnh ảo hóa bởi nhiều máy chủ.
- Hỗ trợ phần cứng: công nghệ KVM cũng có thể sử dụng được nhiều nền tảng phần cứng được Linux hỗ trợ.
- Quản lý bộ nhớ: KVM VPS được hưởng các chức năng quản lý bổ nhớ của Linux, chúng hỗ trợ truy cập bộ nhớ không đồng nhất, hợp nhất kernel cùng tran. Bộ nhớ ảo hóa KVM có khả năng hoán đổi có hiệu suất tốt, được chia sẻ hoặc sao lưu bởi một file đĩa.
- Di chuyển công nghệ ảo hóa KVM trực tiếp: KVM cho phép bạn di chuyển ảo hóa trực tiếp – di chuyển một chương trình ảo hóa đang chạy mà không gây ra sự gián đoán giữa các máy chủ vật lý. KVM vẫn được bật, mọi kết nối mạng và ứng dụng vẫn hoạt động bình thường. Đồng thời trong quá trình di chuyển nó thực hiện cả các thao tác lưu trữ.
- Hiệu suất, khả năng mở rộng: Như đã đề cập ở các chức năng trên của ảo hóa KVM, chúng sở hữu các ưu điểm của của Linux, đồng thời chúng sẽ có khả năng mở rộng giúp phù hợp để đáp ứng như cầu khi máy khách và yêu cầu truy cập tăng lên nhiều lần. Công nghệ KVM cho phép khối lượng công việc ứng dụng yêu cầu khắt khe nhất được ảo hóa và là cơ sở cho nhiều thiết lập ảo hóa doanh nghiệp, ví dụ như: trung tâm dữ liệu, máy chủ ảo vps và công nghệ đám mây riêng.
- Độ trễ thấp hơn: Linux có các phần cho phép mở rộng thời gian thực tế để các ứng dụng dựa trên KVM chạy trong một chế độ trễ thấp hơn với mức độ ưu tiên tốt hơn. Và chúng cũng tiến hành phân chia các quá trình yêu cầu một khoảng thời gian dài tính toán thành các khoảng nhỏ hơn, rồi sau đó lên lịch để xử lý tương ứng.
- Quản lý với KVM: Thông qua KVM cho phép quản lý thủ công chương trình ảo hóa được kích hoạt từ máy trạm, không cần qua công cụ quản lý. Chức năng này thường được sử dụng bởi các doanh nghiệp lớn để quản trị nguồn tài nguyên, tăng khả năng phân tích dữ liệu, hợp lý các hoạt động.
III. Cài đặt và chạy 1 VPS đơn giản bằng KVM.
– Cập nhật hệ thống.
apt-get update -y
apt-get upgrade -y
– Cài đặt KVM và các gói liên quan.
apt install qemu-kvm libvirt-clients libvirt-daemon-system bridge-utils virt-manager cloud-image-utils -y
– Tạo thư mục và tải image.
cd /home/
wget https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img
# wget https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.ova
– Tạo ssh keypair.
Trong đó các option : -t : type , -b : byte , -f : output key-gen ,-C : comment ,-N : new_passphrase (chi tiết các option xem tại đây).
cd /home/
ssh-keygen -t rsa -b 4096 -f id_rsa -C ubuntu-testing -N "" -q
– Cấu hình Cloud-config
Để cấu hình máy ảo cho lần khởi động đầu tiên , ta cần phải tạo ra một file cloud-config chứa thông tin cấu hình mà máy ảo sẽ được tạo . Trong file config này chứa các module mà cloud-init đọc và thực thi lệnh dựa trên những module đó . Chi tiết các module của cloud-init các bạn có thể tìm đọc tại đây
Ở ví dụ dưới ta sẽ tạo ra một file cloud-config đơn giản có nhiệm vụ tạo ra một user lam có thể đăng nhập bằng user/password và một user ubuntu chỉ cho phép đăng nhập qua giao thức ssh . Thêm một nhiệm vụ nữa là mình sẽ disable cloud-init service để nó chỉ có thể chạy duy nhất lần đầu tiên khi tạo máy ảo còn các lần sau thì không khởi động lên nữa . Mình sẽ nói lí do về cuối bài viết .
echo """
#cloud-config
hostname: ubuntu
fqdn: hoanghd.com
manage_etc_hosts: true
users:
- name: ubuntu
sudo: ALL=(ALL) NOPASSWD:ALL
groups: users, admin
home: /home/ubuntu
shell: /bin/bash
lock_passwd: true
ssh-authorized-keys:
- $(cat id_rsa.pub)
- name: hoanghd
sudo: ALL=(ALL) NOPASSWD:ALL
groups: users, admin
home: /home/hoanghd
shell: /bin/bash
lock_passwd: false
# only cert auth via ssh (console access can still login)
ssh_pwauth: false
disable_root: false
chpasswd:
list: |
hoanghd:Hoanghd164
expire: False
bootcmd:
- sudo touch /etc/cloud/cloud-init.disabled""" > /home/cloud_init.cfg
– Tạo 1 snapshot cho vps
Bước này ta tạo một ổ đĩa mới có backing file trỏ tới file image gốc , file qcow2 này có đặc điểm chỉ lưu thông tin khác nhau giữa chính nó với image gốc ( ở ví dụ bên dưới thì ta tăng bộ nhớ của image gốc từ 2GB thành bộ nhớ ảo 10GB với ổ đĩa mới ) . Lợi ích của cách tạo file này là không những không tác động tới image gốc do các thông tin chỉnh sửa được thể hiện qua ổ đĩa mới vừa tạo ra , đồng thời cũng tiết kiệm không gian bộ nhớ do không phải clone lại image gốc và có thể gia tăng bộ nhớ ảo so với bộ nhớ thật của image gốc .
qemu-img create -b /home/bionic-server-cloudimg-amd64.img -f qcow2 /home/snapshot-bionic-server-cloudimg.qcow2 10G
– Verify lại snapshot.
$ qemu-img info snapshot-bionic-server-cloudimg.qcow2
image: snapshot-bionic-server-cloudimg.qcow2
file format: qcow2
virtual size: 10G (10737418240 bytes)
disk size: 196K
cluster_size: 65536
backing file: bionic-server-cloudimg-amd64.img
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false
– Bước này chúng ta cấu hình một mạng tĩnh, các bạn cũng có thể tìm hiểu thêm chi tiết ở đây.
echo '''version: 2
ethernets:
ens3:
dhcp4: false
addresses: [ 172.16.2.241/24 ]
gateway4: 172.16.2.254
nameservers:
addresses: [ 1.1.1.1,8.8.8.8 ]'''> /home/network_config_static.cfg
Trong cloud-init , khái niệm datasource là chỉ các thông tin mà máy ảo cần để cấu hình cho lần đầu tiên boot lên. Ở ví dụ bên dưới , ta nén các thông tin cấu hình máy ảo mà ta tạo ra trước đó ở hai file cloud_init.cfg và cấu hình mạng tĩnh network_config_static.cfg và trong trong ổ đĩa ubuntu-seed.qcow2 .
Cloud-localds là một tools trong cloud-init với nhiệm vụ tạo ra các datasource NoCloud .
cloud-localds -v --network-config=/home/network_config_static.cfg /home/ubuntu-seed.qcow2 /home/cloud_init.cfg
– Verify lại network.
$ qemu-img info ubuntu-seed.qcow2
image: ubuntu-seed.qcow2
file format: raw
virtual size: 368K (376832 bytes)
disk size: 368K
– Phân quyền user root cho VPS.
sudo sed -i 's|#group = "root"|group = "root"|' /etc/libvirt/qemu.conf
sudo sed -i 's|#user = "root"|user = "root"|' /etc/libvirt/qemu.conf
systemctl restart libvirtd
– Thêm nội dung sau vào /etc/sysctl.conf
echo '''net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0''' >> /etc/sysctl.conf
– Cập nhật lại sysctl
modprobe br_netfilter
sysctl -p /etc/sysctl.conf
# Output
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0
– Hãy nhìn lại thông tin card mạng trước khi tạo bridge, ta có card mạng chính là ens33.
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:57:40:02 brd ff:ff:ff:ff:ff:ff
inet 172.16.2.253/24 brd 172.16.2.255 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe57:4002/64 scope link
valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:75:88:82 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:75:88:82 brd ff:ff:ff:ff:ff:ff
– Tạo 1 card mạng bridge, mình tạo card này có tên là br0 và gắn card bridge này với card mạng chính có tên là ens33. Hãy xác định tên file cấu hình netplan của bạn thật chính xác nhé, vì file của bạn có thể sẽ có nội dung hoặc tên file khác của mình.
$ ll /etc/netplan/50-cloud-init.yaml
-rw-r--r-- 1 root root 535 Nov 24 2022 /etc/netplan/50-cloud-init.yaml
Nội dung của file /etc/netplan/50-cloud-init.yaml như sau:
echo '''network:
version: 2
renderer: networkd
ethernets:
ens33:
dhcp4: false
dhcp6: false
bridges:
br0:
interfaces: [ens33]
addresses: [172.16.2.253/24]
gateway4: 172.16.2.254
mtu: 1500
nameservers:
addresses: [8.8.8.8,1.1.1.1]
parameters:
stp: true
forward-delay: 4
dhcp4: no
dhcp6: no''' > /etc/netplan/50-cloud-init.yaml
Hãy cập nhật lại thông tin network bằng 2 lệnh dưới.
sudo netplan generate
sudo netplan --debug apply
# Output
sudo netplan --debug apply
** (generate:1800): DEBUG: 17:50:52.086: Processing input file /etc/netplan/50-cloud-init.yaml..
** (generate:1800): DEBUG: 17:50:52.086: starting new processing pass
** (generate:1800): DEBUG: 17:50:52.087: We have some netdefs, pass them through a final round of validation
** (generate:1800): DEBUG: 17:50:52.087: br0: setting default backend to 1
** (generate:1800): DEBUG: 17:50:52.087: Configuration is valid
** (generate:1800): DEBUG: 17:50:52.087: ens33: setting default backend to 1
** (generate:1800): DEBUG: 17:50:52.088: Configuration is valid
** (generate:1800): DEBUG: 17:50:52.088: Generating output files..
** (generate:1800): DEBUG: 17:50:52.088: NetworkManager: definition ens33 is not for us (backend 1)
** (generate:1800): DEBUG: 17:50:52.089: NetworkManager: definition br0 is not for us (backend 1)
DEBUG:netplan generated networkd configuration changed, restarting networkd
DEBUG:no netplan generated NM configuration exists
DEBUG:ens33 not found in {}
DEBUG:br0 not found in {}
DEBUG:Merged config:
network:
bonds: {}
bridges:
br0:
addresses:
- 172.16.2.253/24
dhcp4: false
dhcp6: false
gateway4: 172.16.2.254
interfaces:
- ens33
mtu: 1500
nameservers:
addresses:
- 8.8.8.8
- 1.1.1.1
parameters:
forward-delay: 4
stp: true
ethernets:
ens33:
dhcp4: false
dhcp6: false
vlans: {}
wifis: {}
DEBUG:Skipping non-physical interface: lo
DEBUG:Skipping composite member ens33
DEBUG:Skipping non-physical interface: virbr0
DEBUG:Skipping non-physical interface: virbr0-nic
DEBUG:{}
DEBUG:netplan triggering .link rules for lo
DEBUG:netplan triggering .link rules for ens33
DEBUG:netplan triggering .link rules for virbr0
DEBUG:netplan triggering .link rules for virbr0-nic
Ở bước cập nhật lại network sau khi chạy lệnh netplan –debug apply, server của bạn sẽ mất kết nối 1 lát và sau đó sẽ tự động kết nối lại nếu file cấu hình của bạn thiết lập chính xác.
Và đây là kết quả sau khi chạy lệnh netplan –debug apply thành công. Bây giờ bạn đã thấy ip address đã được gỡ ra từ card mạng chính có tên ens33 và gắn sang cho card bridge có tên là br0.
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
link/ether 00:0c:29:57:40:02 brd ff:ff:ff:ff:ff:ff
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:75:88:82 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:75:88:82 brd ff:ff:ff:ff:ff:ff
5: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether a2:bf:c6:8b:51:5c brd ff:ff:ff:ff:ff:ff
inet 172.16.2.253/24 brd 172.16.2.255 scope global br0
valid_lft forever preferred_lft forever
inet6 fe80::a0bf:c6ff:fe8b:515c/64 scope link
valid_lft forever preferred_lft forever
– Verify type bridge
$ ip link show type bridge
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000
link/ether 52:54:00:75:88:82 brd ff:ff:ff:ff:ff:ff
5: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether a2:bf:c6:8b:51:5c brd ff:ff:ff:ff:ff:ff
$ brctl show
bridge name bridge id STP enabled interfaces
br0 8000.a2bfc68b515c yes ens33
virbr0 8000.525400758882 yes virbr0-nic
– Tạo card bridged-network
cat > /home/bridged-network.xml << OEF
<network>
<name>bridged-network</name>
<forward mode="bridge" />
<bridge name="br0" />
</network>
OEF
– Define bridged-network
virsh net-define bridged-network.xml
– Start bridged-network
virsh net-start bridged-network
– Bật chế độ tự khởi động cho card bridged-network
virsh net-autostart bridged-network
– Verify net-list
$ virsh net-list
Name State Autostart Persistent
----------------------------------------------------------
bridged-network active yes yes
default active yes yes
– Start VPS.
Ở bước này ta sử dụng virt-install để tạo ra một domain với các thông số như ở bên dưới , domain này được attach với file ubuntu-seed.qcow2 và file snap-shot.qcow2 dùng để cloud init đọc trong quá trình cấu hình máy ảo khi khởi động lên.
virt-install --name ubuntu \
--virt-type kvm --memory 2048 --vcpus 2 \
--boot hd,menu=on \
--disk path=ubuntu-seed.qcow2,device=cdrom \
--disk path=snapshot-bionic-server-cloudimg.qcow2,device=disk \
--graphics vnc \
--os-type Linux --os-variant ubuntu18.04 \
--network network:bridged-network \
--console pty,target_type=serial \
--noautoconsole
#Output
Starting install...
Domain creation completed.
– Sau khi tạo xong , ta check xem máy ảo đã được booting hay chưa.
$ virsh list --all
Id Name State
----------------------------------------------------
1 ubuntu running
– Console vào VPS.
$ virsh console ubuntu
Connected to domain ubuntu
Escape character is ^]
Ubuntu 18.04.6 LTS ubuntu ttyS0
ubuntu login: ci-info: no authorized SSH keys fingerprints found for user ubuntu.
ci-info: no authorized SSH keys fingerprints found for user hoanghd.
<14>Nov 23 17:54:47 cloud-init: #############################################################
<14>Nov 23 17:54:47 cloud-init: -----BEGIN SSH HOST KEY FINGERPRINTS-----
<14>Nov 23 17:54:47 cloud-init: 1024 SHA256:FlIeRklKiPs7/IHcawyWtik8HN1uJrowo8/KUue8LLw root@ubuntu (DSA)
<14>Nov 23 17:54:47 cloud-init: 256 SHA256:vH6ujk6QhrsrzlXos5z7qC4B2ZiSsH4yrnmycBJaA+o root@ubuntu (ECDSA)
<14>Nov 23 17:54:47 cloud-init: 256 SHA256:+ykhQOt5SNn18IjQvxuF1JhwaofEK4E/9Y32Q9yklhY root@ubuntu (ED25519)
<14>Nov 23 17:54:47 cloud-init: 2048 SHA256:wtSvh3WVK86VNN/GNU+qh+hbvtgFyqUNrCUneSnwymY root@ubuntu (RSA)
<14>Nov 23 17:54:47 cloud-init: -----END SSH HOST KEY FINGERPRINTS-----
<14>Nov 23 17:54:47 cloud-init: #############################################################
-----BEGIN SSH HOST KEY KEYS-----
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIoKydpamL5g0cdE5ImUDV0zWBmtrx/nIvmct4+jgv0pG+gV7NAmd6UDws6taqo+KcWx6PVFS27qw6jBZ4QhkTI= root@ubuntu
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDlKL5TrqcTAu+aGMoLlE/VfQn2GHXTrxdErxdG7E+Ja root@ubuntu
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCTmU0XPgcrvOxRFtuWxnK3PrnWlHh3HecNEofPtxzRM9BhF3CfSUviKcmu/AbSvPRWpIltxfeg7Gp2Ldesu71eP5ehia94jAIpPF8ZnLCpRg0aZYK9P049SsLGk8HNC1YsdmlDpyUwswmYvEOtPe/C3YHeKQkeRG880PFlONNrE7PRYbd2yv/vxkXVfDXaXEJJaffF5eMul4c49iPQLFwVJxL4bEwJoOs9HZSzQ4B+hTnG4laz8dkSuOr863MJi/LaGUP2zuljJnnVlMvibxxZpqeMBTNPGR6b9Or75cGkPFREH51IyNzgPKvOq0leuxWhHYBDOi2V0jAlBntutDq1 root@ubuntu
-----END SSH HOST KEY KEYS-----
Ubuntu 18.04.6 LTS ubuntu ttyS0
ubuntu login:
Đăng nhập với thông tin dưới như đã khai báo ở phần trên.
Login : hoanghd
Pass: Hoanghd164
Sau khi login xong, bạn hãy kiểm tra ip address của vps xem đã đúng như những gì bạn khai báo chưa.
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:54:00:e8:9b:a0 brd ff:ff:ff:ff:ff:ff
inet 172.16.2.241/24 brd 172.16.2.255 scope global ens3
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fee8:9ba0/64 scope link
valid_lft forever preferred_lft forever
Bạn cũng có thể show route table.
$ ip r
default via 172.16.2.254 dev ens3 proto static
172.16.2.0/24 dev ens3 proto kernel scope link src 172.16.2.241
Và sau đó check kết nối ra internet.
$ ping hoanghd.com
PING hoanghd.fun (103.138.89.144) 56(84) bytes of data.
64 bytes from 103.138.89.144 (103.138.89.144): icmp_seq=1 ttl=55 time=6.00 ms
64 bytes from 103.138.89.144 (103.138.89.144): icmp_seq=2 ttl=55 time=5.75 ms
64 bytes from 103.138.89.144 (103.138.89.144): icmp_seq=3 ttl=55 time=5.58 ms
64 bytes from 103.138.89.144 (103.138.89.144): icmp_seq=4 ttl=55 time=5.98 ms
--- hoanghd.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3009ms
rtt min/avg/max/mdev = 5.584/5.832/6.005/0.190 ms
Ta thấy cách này khá là thủ công vì phải gõ từng dòng lệnh , ta có thể tạo ra 1 bash shell scripts để chạy lênh này hoặc có thể tạo ra domain này từ file xml bằng cách sau khi khởi tạo máy ảo xong , ta đăng nhập vào VM và dùng lệnh
virsh dumpxml domain-name > ubuntu-bionic.xml
Cấu hình của domain vừa tạo sẽ được xuất ra file ubuntu-bionic.xml , sau đó mỗi khi muốn tạo lại domain từ file cloud-image , ta chỉ cần gõ lệnh
virsh create domain-name
Khi check lại domain ta cũng sẽ thấy máy ảo tương tự khi dùng virsh-install ( chú ý destroy máy ảo trước để tránh conflict)
– Xóa VPS
virsh shutdown ubuntu
virsh destroy ubuntu
virsh undefine ubuntu
rm -rf /home/snapshot-bionic-server-cloudimg.qcow2 /home/ubuntu-seed.qcow2
– Tại bước này ta sẽ đăng nhập vào máy bảo bằng giao thức ssh qua user ubuntu
ssh ubuntu@192.168.122.158 -i id_rsa
# final cloud-init status
cat /run/cloud-init/result.json
# cloud logs
vi /var/log/cloud-init.log
vi /var/log/cloud-init-output.log
– Disable cloud-init service.
Tại sao phải vô hiệu hóa cloud-init khi đã tạo xong máy ảo? Trong thực tế , ta chỉ nên để cloud-init service chạy 1 lần duy nhất khi khởi tạo domain lần đầu tiên , tránh việc khi restart lại domain thì cloud-init service cũng khởi động lại và thực hiện lặp lại quá trình cấu hình máy ảo và có thể gây lỗi không mong muốn. Lệnh cmd trong file cloud_init.cfg.
bootcmd:
- sudo touch /etc/cloud/cloud-init.disabled
Lệnh này tạo ra 1 file cloud-init.disable có tác dụng disable cloud-init , khi mỗi lần khởi động bằng systemd , 1 generator được tạo ra và quyết định service cloud-init có được chạy không bằng cách kiểm tra file cloud-init.disable có tồn tại không . Nếu có nó sẽ vô hiệu hóa cloud-init mỗi lần khởi động lại máy ảo. Cũng có nhiều cách để disable cloud-init nhưng mình chỉ nêu ví dụ cách này. Hãy lưu file public key vào biến môi trường.