Welcome to the eighth part of our technical wiki series on Linux administration!
After we covered fundamentals, process management, network configuration, shell scripting, backup strategies, and system security in previous articles, we now turn to virtualization and VM management.
Virtualization is a fundamental component of modern IT infrastructures today.
⚠️ Note: In this article, we use Ubuntu/Debian as the example distribution. The basic concepts are the same on all Linux systems, but package installation and some configuration paths may vary depending on the distribution. If you use a different distribution, please consult the relevant documentation for the specific installation commands and paths.
Virtualization Fundamentals
Virtualization is a fundamental technology of modern IT infrastructures. It transforms physical server resources into flexible, isolated environments, enabling more efficient resource utilization. The virtualization of servers, networks, and storage systems forms the backbone of many data centers and cloud environments today.
┌─ Virtualization Layers ─────────────────────────────────────┐
│ Physical Computer │
│ (CPU, RAM, Hard Disk) │
├─────────── Hypervisor ──────────────────────────────────────┤
│ Manages and distributes │
│ all resources │
├─────────── VMs ─────────────────────────────────────────────┤
│ VM1 │ VM2 │ VM3 │ VM4 │
│ Linux │ Windows │ Linux │ BSD │
└─────────────────────────────────────────────────────────────┘
Why virtualization?
- Resource efficiency: Better use of hardware
- Isolation: Each VM runs independently of the others
- Flexibility: Fast creation and deletion of VMs
- Security: Separated environments for different purposes
- Testing: Risk-free testing of new configurations
Understanding hypervisor types:
- Type 1 (Bare-Metal)
- Runs directly on the hardware
- Higher performance
- Examples:
KVM,VMware ESXi,Xen - Typical for servers and data centers
- Type 2 (Hosted)
- Runs as a program on an operating system
- Easier to install and manage
- Examples:
VirtualBox,VMware Workstation - Good for desktop and development
KVM/QEMU in Detail
KVM (Kernel-based Virtual Machine) and QEMU form the foundation of Linux virtualization. KVM, as a kernel module, provides virtualization functions at the hardware level, while QEMU handles the emulation of virtual hardware. This combination enables an efficient and flexible virtualization environment.
- KVM is the blueprint and structure
- QEMU provides the furniture and setup
- Together they create complete "apartments" (VMs)
How does the interaction work?
┌─ Virtualization Stack in Detail ────────────────────────────┐
│ virt-manager (Graphical Interface) │
│ virsh (Command Line) │
│ Cockpit (Web Interface) │
├─────────── libvirt ─────────────────────────────────────────┤
│ Management API │
│ Configuration Management │
│ VM Definitions │
├─────────── QEMU/KVM ────────────────────────────────────────┤
│ QEMU: Hardware Emulation │
│ KVM: Kernel Module for Virtualization │
│ Resource Management │
├─────────── Hardware ────────────────────────────────────────┤
│ CPU with Virtualization Support │
│ Main Memory │
│ Disk Storage │
└─────────────────────────────────────────────────────────────┘
Step-by-Step Installation:
a) Checking Hardware Requirements
egrep -c '(vmx|svm)' /proc/cpuinfo
# If the output is greater than 0, your CPU supports virtualization
b) Installing Required Packages
sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst virt-manager
c) Setting Up User Permissions
sudo usermod -aG libvirt $USER
sudo usermod -aG kvm $USER
d) Checking Services
sudo systemctl status libvirtd
# Should display "active (running)"
VM Creation in Detail
Creating a virtual machine is similar to configuring a physical system. Virtual components like CPU, RAM, and hard disk are provided from the host system's resources and can be flexibly adapted to the respective requirements.
a) Preparing the Environment
# Create storage pool for VM images
sudo virsh pool-define-as --name vmpool --type dir --target /var/lib/libvirt/images
# Activate storage pool
sudo virsh pool-build vmpool
sudo virsh pool-start vmpool
sudo virsh pool-autostart vmpool
b) Preparing the ISO Image
# Create directory for ISO images
sudo mkdir -p /var/lib/libvirt/images/iso
# Download ISO image (example: Ubuntu Server)
sudo wget https://releases.ubuntu.com/22.04/ubuntu-22.04.3-live-server-amd64.iso \
-O /var/lib/libvirt/images/iso/ubuntu-22.04.3-server.iso
c) Creating a VM via Command Line
virt-install \
--name ubuntu-server \
# VM name for management
--memory 2048 \
# RAM in MB (here 2GB)
--vcpus 2 \
# Number of virtual CPU cores
--disk size=20,format=qcow2 \
# Disk size and format
--os-variant ubuntu22.04 \
# Optimizations for the operating system
--network bridge=virbr0 \
# Network configuration
--graphics vnc \
# Graphical console via VNC
--console pty,target_type=serial
# Text console for installation
d) Parameters explained in detail:
- –memory (RAM allocation)
- Minimum: 1024 MB for modern systems
- Recommended: 2048 MB for servers
- Maximum: Depends on the host system
- Tip: Leave enough RAM for the host system
- –vcpus (Virtual CPUs)
- Minimum: 1 CPU for basic servers
- Standard: 2 CPUs for normal workloads
- Maximum: Not more than physical CPU cores
- Tip: Reserve cores for the host system
- –disk (Disk configuration)
- size: Size in GB
format:
- qcow2: Dynamically growing, space-saving
- raw: Fixed size, better performance
- Tip: Plan enough storage space for updates
- –network (Network connection)
- bridge: Direct network access
- nat: Routed via host (default)
- none: No network
- Tip: virbr0 is the default NAT bridge
e) Advanced Network Options
Network configuration is crucial for VM communication. There are different network modes suitable for different use cases:
┌─ Network Modes ─────────────────────────────────────────────┐
│ - Default Mode │
│ - Internet via Host │
│ - VM not visible from outside │
├─────────── Bridge ──────────────────────────────────────────┤
│ - Direct network access │
│ - VM like a physical computer │
│ - Full network access │
├─────────── Internal ────────────────────────────────────────┤
│ - VM-to-VM communication only │
│ - Isolated network │
│ - Higher security │
└─────────────────────────────────────────────────────────────┘
Create NAT network:
- virsh net-define nat-network.xml
- virsh net-start nat-network
- virsh net-autostart nat-network
Set up bridge network:
# In /etc/network/interfaces:
auto br0
iface br0 inet dhcp
bridge_ports enp0s3
bridge_stp on
bridge_fd 0
VM Management and Monitoring
Managing virtual machines is one of the core tasks in a virtualization environment. VMs are independent systems running on a physical host system. Their efficient management and continuous monitoring are crucial for stable operation.
┌─ VM Management Components ──────────────────────────────────┐
│ - Start/Stop/Pause │
│ - Snapshots │
│ - Backup/Restore │
├─────────── Monitoring ──────────────────────────────────────┤
│ - Resource Utilization │
│ - Performance Metrics │
│ - System Status │
├─────────── Maintenance ─────────────────────────────────────┤
│ - Updates │
│ - Optimization │
│ - Troubleshooting │
└─────────────────────────────────────────────────────────────┘
a) Basic VM Management
Your VMs have different states:
- Running: VM is running and consuming resources
- Paused: VM is paused but still in memory
- Shutdown: VM is completely shut down
- Saved: State has been saved for later startup
# Display VM status
virsh list --all
# Shows:
Id Name Status
--------------------------------
1 ubuntu-server running
- debian-test shut off
b) Daily Management Tasks
Starting a VM:
# Start VM normally
virsh start ubuntu-server
# Check status
virsh domstate ubuntu-server
Shutting down a VM:
# Graceful shutdown (via ACPI signal)
virsh shutdown ubuntu-server
# Force hard power-off (only in emergency!)
virsh destroy ubuntu-server
c) Snapshot Management
A snapshot is like a photo of your VM at a specific point in time. You can later return to this state if something goes wrong.
┌─────────── Snapshot Types ──────────────────────────────────┐
│ Disk-Only Snapshot: │
│ - Saves only the disk state │
│ - Lower storage requirement │
│ - VM can continue running during the process │
├─────────────────────────────────────────────────────────────┤
│ Internal / Full Snapshot: │
│ - Complete VM state including RAM content │
│ - Enables direct resumption at the exact state point │
│ - VM is briefly paused during creation │
└─────────────────────────────────────────────────────────────┘
Creating and managing snapshots:
# Create snapshot
virsh snapshot-create-as ubuntu-server snapshot1 "Before the update"
# Snapshot with RAM state
virsh snapshot-create-as ubuntu-server snapshot2 "Before update" --memspec
# Display all snapshots
virsh snapshot-list ubuntu-server
# Display snapshot details
virsh snapshot-info ubuntu-server snapshot1
# Revert to snapshot
virsh snapshot-revert ubuntu-server snapshot1
┌─────────── Snapshot Hierarchy ──────────────────────────────┐
│ Base Image (ubuntu-server.qcow2) │
│ │ │
│ ├── Snapshot 1 (After Base Installation) │
│ │ └── Snapshot 2 (After System Updates) │
│ │ └── Snapshot 3 (Current Live State) │
│ │ │
│ └── Backup Snapshot (Separate Branch / Rollback State) │
└─────────────────────────────────────────────────────────────┘
Important notes for snapshots:
- Create snapshot before major changes (updates, configurations)
- Snapshots are not a backup replacement
- Regularly clean up old snapshots
- Disk-Only snapshots save storage space
- Performance degradation with many snapshots
🔧 Practical example: VM monitoring in practice
Continuous monitoring of virtual machines is a central aspect of VM management. Effective monitoring helps detect performance problems early and optimize resource utilization.
Here are the most important monitoring tools:
┌─ Monitoring Areas ──────────────────────────────────────────┐
│ CPU Usage │
│ Main Memory │
│ Disk Usage │
├─────────── Status ──────────────────────────────────────────┤
│ Uptime │
│ Network Activity │
│ System Status │
├─────────── Logs ────────────────────────────────────────────┤
│ System Logs │
│ Error Messages │
│ Performance Data │
└─────────────────────────────────────────────────────────────┘
Basic monitoring commands:
# Detailed information about a VM
virsh dominfo ubuntu-server
# Shows:
# - CPU usage
# - Memory utilization
# - Uptime
# - Status
# Real-time statistics
virt-top
# Similar to 'top', but specifically for VMs:
# - CPU usage per VM
# - Memory usage
# - I/O activity
┌─ VM Monitoring System ──────────────────────────────────────┐
│ ┌─── VM1 ───┐ ┌─── VM2 ───┐ ┌─── VM3 ───┐ │
│ │CPU: 30% │ │CPU: 50% │ │CPU: 20% │ │
│ │RAM: 2GB │ │RAM: 4GB │ │RAM: 1GB │ │
│ │Disk: 50% │ │Disk: 70% │ │Disk: 30% │ │
│ └───────────┘ └───────────┘ └───────────┘ │
│ │
│ ┌─────────── Monitoring Tools ────────────┐ │
│ │ - virsh domstats → Status & Stats │ │
│ │ - virt-top → Live Monitoring │ │
│ │ - domblkstat → Disk Performance │ │
│ │ - domifstat → Network Stats │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Monitoring Flow:
┌─── Data Collection ──┐ ┌── Analysis ──┐ ┌── Action ──┐
│ CPU Usage │ ──> │ Evaluation │ ──> │ Alerts │
│ RAM Utilization │ │ Trends │ │ Adjustment │
│ Disk I/O │ │ Thresholds │ │ Scaling │
└──────────────────────┘ └──────────────┘ └────────────┘
f) Advanced Monitoring Functions
A proactive monitoring system enables early detection and resolution of potential problems. Various metrics play an important role in this.
┌─────────── Monitoring Areas ────────────────────────────────┐
│ Performance: │
│ - CPU usage and load peaks │
│ - Memory and ballooning statistics │
│ - Disk usage and I/O latencies │
├─────────────────────────────────────────────────────────────┤
│ Network & Status: │
│ - Throughput, packet loss and latencies │
│ - Socket states and connections │
│ - Availability of virtual services │
└─────────────────────────────────────────────────────────────┘
Performance monitoring:
# Monitor CPU and memory of a VM
virt-top
# Detailed VM statistics
virsh domstats ubuntu-server
# Display resource usage
virsh dommemstat ubuntu-server
virsh cpu-stats ubuntu-server
Network monitoring:
# Display network interfaces
virsh domiflist ubuntu-server
# Network statistics
virsh domifstat ubuntu-server vnet0
Disk monitoring:
# Display disk usage
virsh domblklist ubuntu-server
# Detailed block device statistics
virsh domblkstat ubuntu-server vda
g) Best Practices for VM Monitoring
┌─ Monitoring Strategy ───────────────────────────────────────┐
│ - CPU Usage │
│ - RAM Usage │
│ - Disk Space │
│ - Network Load │
├─────────── Advanced ────────────────────────────────────────┤
│ - Performance Metrics │
│ - Service Status │
│ - Log Analysis │
├─────────── Automation ──────────────────────────────────────┤
│ - Alert Messages │
│ - Reports │
│ - Trending │
└─────────────────────────────────────────────────────────────┘
🔧 Practical example: Implementing a monitoring routine
Regular checks:
# Hourly resource check
watch -n 3600 'virsh domstats ubuntu-server | grep "cpu\|balloon"'
# Daily disk check
virsh domblkstat ubuntu-server vda --human
# Weekly performance analysis
virt-top -n 1 > /var/log/vm_performance_$(date +%Y%m%d).log
Setting up alerts:
# Example script for automatic resource alerts
if virsh dommemstat ubuntu-server | awk '/actual/ {if($2>90) print "Warning: High Memory Usage"}'; then
echo "VM Memory Critical" | mail -s "VM Alert" admin@domain.com
fi
VM Backup and Migration
1. Backup
Regular backup of virtual machines is a critical aspect of VM management. A well-thought-out backup concept not only protects against data loss but also enables quick recovery in case of errors.
┌─────────── Backup Types ────────────────────────────────────┐
│ Full Backup: Complete VM and all virtual disks │
│ Incremental: Saves only changes since last state │
│ Snapshot: Short-term snapshot for maintenance │
├─────────────────────────────────────────────────────────────┤
│ Backup Process: │
│ │
│ [ Source VM ] ──> [ Backup Tool ] ──> [ Storage Target ] │
│ (Source) (virsh/qemu) (NAS / S3) │
│ │ │ │ │
│ └─ Check VM └─ Save Delta └─ Archive │
└─────────────────────────────────────────────────────────────┘
🔧 Practical example: Applying VM backup methods
There are different backup methods you should know and learn so that you can apply them:
┌─────────── Backup Methods Compared ─────────────────────────┐
│ Full Backup: Complete VM and all virtual disks │
│ Incremental: Only changes since last backup │
│ Differential: Changes since last full backup │
├─────────────────────────────────────────────────────────────┤
│ Backup Process in Detail: │
│ │
│ [ Source VM ] ──> [ Snapshot ] ──> [ Export ] ──> [ Test ] │
│ Running Guest Consistent qemu-img Verify │
│ is backed up State in RAM Copy / Tar Check │
└─────────────────────────────────────────────────────────────┘
b) Full VM Backup
# Stop VM (for offline backup)
virsh shutdown ubuntu-server
# Save configuration
virsh dumpxml ubuntu-server > /backup/ubuntu-server.xml
# Copy disk image
cp /var/lib/libvirt/images/ubuntu-server.qcow2 /backup/
c) Incremental Backup Methods
Incremental backups save only the changes since the last backup. This saves storage space and time.
┌─────────── Backup Hierarchy & Restore Chain ────────────────┐
│ Day 1 (Sun): Full Backup (Base Image saved) │
│ Day 2 (Mon): Incremental 1 (Delta to Day 1) │
│ Day 3 (Tue): Incremental 2 (Delta to Day 2) │
│ Day 4 (Wed): Incremental 3 (Delta to Day 3) │
├─────────────────────────────────────────────────────────────┤
│ Recovery (Restore Pipeline): │
│ │
│ [ Full Backup ] ─> [ Incr. 1 ] ─> [ Incr. 2 ] ─> [ Incr. 3 ]│
│ │
│ 1. Restore 2. Apply Mon 3. Apply Tue 4. Apply Wed │
│ base state Delta Delta Live State │
└─────────────────────────────────────────────────────────────┘
🔧 Practical example: Implementing a monitoring routine
# Create full backup (Day 1)
qemu-img create -f qcow2 ubuntu-server-base.qcow2
# Create incremental backup (Day 2)
qemu-img create -f qcow2 -b ubuntu-server-base.qcow2 ubuntu-server-incr1.qcow2
# Create another incremental backup (Day 3)
qemu-img create -f qcow2 -b ubuntu-server-incr1.qcow2 ubuntu-server-incr2.qcow2
d) Backup Best Practices
A well-thought-out backup strategy is fundamental for secure operation of virtual machines. The following practices have proven effective in professional system administration.
┌─ Backup Strategy ───────────────────────────────────────────┐
│ - What is being backed up? │
│ - How often is it backed up? │
│ - Where is it backed up? │
├─────────── Implementation ──────────────────────────────────┤
│ - Automation │
│ - Monitoring │
│ - Verification │
├─────────── Recovery ────────────────────────────────────────┤
│ - Test Procedures │
│ - Documentation │
│ - Emergency Plan │
└─────────────────────────────────────────────────────────────┘
1. The 3-2-1 Backup Rule:
- 3 copies of your data
- 2 different storage media
- 1 copy at a different location
2. Automation with Cron:
# Backup script example
#!/bin/bash
# Shut down VM or create snapshot
virsh shutdown ubuntu-server
# Wait until VM is stopped
sleep 30
# Create backup
cp /var/lib/libvirt/images/ubuntu-server.qcow2 /backup/
# Start VM again
virsh start ubuntu-server
# Daily backup at 2 AM
0 2 * * * /usr/local/bin/vm-backup.sh
2. Migration
As an administrator, you sometimes need to move VMs from one host to another. There are several reasons for this:
- Hardware upgrades
- Load balancing
- Maintenance work
- Disaster recovery
┌─────────── Migration Types ─────────────────────────────────┐
│ Cold Migration: VM stopped (offline transfer of disks) │
│ Live Migration: VM continues running (RAM & CPU synced) │
├─────────────────────────────────────────────────────────────┤
│ Migration Process: │
│ │
│ [ Source Host ] ───> [ Transfer ] ───> [ Target Host ] │
│ (Source Server) (10G / SSH) (Target Server) │
│ │ │ │ │
│ └─ Prepare VM └─ Sync Disks └─ Start VM │
└─────────────────────────────────────────────────────────────┘
Performing live migration:
# Check prerequisites
# 1. Test network connection
ping target-host
# 2. Set up SSH access
ssh-copy-id target-host
# 3. Check shared storage
virsh pool-list --all
# Start live migration
virsh migrate --live ubuntu-server qemu+ssh://target-host/system --verbose --persistent --undefinesource
Storage Migration
Storage migration is like moving your VM hard disks. This may be necessary for:
- Performance optimization
- Storage space management
- Hardware upgrades
- Maintenance work
┌─────────── Storage Migration Types ─────────────────────────┐
│ Offline: VM stopped, consistent copying of disks │
│ Online: VM active, qemu blockcopy / block-stream Live │
├─────────────────────────────────────────────────────────────┤
│ Storage Migration Process: │
│ │
│ [ Source Storage ] ──> [ Block Transfer ] ──> [ Target Pool ]│
│ (Local Pool) (virsh blockcopy) (Shared) │
│ │ │ │ │
│ └─ Prepare └─ Mirror └─ Switch│
└─────────────────────────────────────────────────────────────┘
🔧 Practical example:
# Shut down VM
virsh shutdown ubuntu-server
# Migrate storage
virsh vol-download --pool default ubuntu-server.qcow2 /backup/
virsh vol-upload --pool new_storage ubuntu-server.qcow2 /backup/
# Adjust VM configuration
virsh edit ubuntu-server
Cold Migration
Cold migration is a method of moving VMs from one host to another, where the VM is shut down during the transfer.
┌─ Cold Migration Process ────────────────────────────────────┐
│ 1. Shut down VM │
│ 2. Check resources │
│ 3. Test network │
├─────────── Transfer ────────────────────────────────────────┤
│ 4. Copy VM files │
│ 5. Adjust configuration │
├─────────── Activation ──────────────────────────────────────┤
│ 6. Start VM on target │
│ 7. Perform functionality test │
└─────────────────────────────────────────────────────────────┘
Advantages of cold migration:
- Safe transfer without data loss
- No resource conflicts during migration
- Enables migration between different CPU architectures (e.g., Intel to AMD)
- Higher compatibility than live migration
Disadvantages:
- Planned downtime required
- Services are unavailable during migration
- Longer interruption of operations
🔧 Practical example:
# 1. Shut down VM
virsh shutdown ubuntu-server
# Wait until VM is stopped
virsh list --all | grep ubuntu-server
# 2. Export VM configuration
virsh dumpxml ubuntu-server > ubuntu-server.xml
# 3. Copy VM files to target host
scp /var/lib/libvirt/images/ubuntu-server.qcow2 \
target-host:/var/lib/libvirt/images/
scp ubuntu-server.xml target-host:/tmp/
# 4. On target host: Define VM
virsh define /tmp/ubuntu-server.xml
# 5. Start VM on target host
virsh start ubuntu-server
3. Best Practices for VM Backup and Migration
┌─ Best Practices Overview ───────────────────────────────────┐
│ - Regular backups │
│ - Different backup types │
│ - Backup tests │
├─────────── Migration ───────────────────────────────────────┤
│ - Check prerequisites │
│ - Minimize downtime │
│ - Create rollback plan │
├─────────── Documentation ───────────────────────────────────┤
│ - Configurations │
│ - Procedures │
│ - Recovery plans │
└─────────────────────────────────────────────────────────────┘
a) Backup Best Practices:
- Regular backups on a fixed schedule
- Combination of full and incremental backups
- Backups on external storage media
- Regular recovery tests
- Documentation of backup procedures
b) Migration Best Practices:
- Thorough planning and preparation
- Compatibility check of systems
- Test migration before the actual migration
- Backup before migration
- Documented rollback strategy
Container Virtualization
1. Docker
Containers are a lightweight alternative to full virtual machines. Think of containers like small, isolated apartments in a large building that all share the same foundation (the kernel).
┌─ Virtualization Comparison ─────────────────────────────────┐
│ App 1 │ App 2 │ App 3 │
│ Libs │ Libs │ Libs │
│ OS │ OS │ OS │
├─────────── Hypervisor ──────────────────────────────────────┤
│ Hardware │
└─────────────────────────────────────────────────────────────┘
┌─────────── Containers ──────────────────────────────────────┐
│ App 1 │ App 2 │ App 3 │
│ Libs │ Libs │ Libs │
├─────────── Container Engine ────────────────────────────────┤
│ OS Kernel │
│ Hardware │
└─────────────────────────────────────────────────────────────┘
Advantages of containers:
- Faster startup (seconds instead of minutes)
- Lower resource consumption
- Easier distribution
- Consistent environments
🔧 Practical example: Docker container workflows
It is important to understand how containers are used in practice:
┌─ Container vs. VM ──────────────────────────────────────────┐
│ App 1 │ App 2 │ App 3 │
│ Libs │ Libs │ Libs │
├─────────── Docker Engine ───────────────────────────────────┤
│ Operating System │
│ Hardware │
└─────────────────────────────────────────────────────────────┘
┌─────────── VMs ─────────────────────────────────────────────┐
│ App+OS │ App+OS │ App+OS │
│ Kernel │ Kernel │ Kernel │
├─────────── Hypervisor ──────────────────────────────────────┤
│ Hardware │
└─────────────────────────────────────────────────────────────┘
Creating and managing containers:
# Install Docker
sudo apt install docker.io
# Check status
sudo systemctl status docker
# Download first container image
sudo docker pull ubuntu:latest
# Start container
sudo docker run -it ubuntu:latest /bin/bash
Container networks and storage
Containers need to communicate with each other and with the outside world. They also need storage space for their data.
┌─ Container Network Types ───────────────────────────────────┐
│ - Default Network │
│ - Container ↔ Container │
│ - Container ↔ Internet │
├─────────── Host ────────────────────────────────────────────┤
│ - Shares host network │
│ - Direct performance │
│ - Less isolation │
├─────────── None ────────────────────────────────────────────┤
│ - No network │
│ - Maximum isolation │
│ - Local access only │
└─────────────────────────────────────────────────────────────┘
Container Storage:
┌─────────── Volumes ─────────────────────────────────────────┐
│ /var/lib/docker/volumes │
│ ├── Web Data │
│ ├── Database │
│ └── Configuration │
├─────────── Bind Mounts ─────────────────────────────────────┤
│ Host ←→ Container │
│ Direct filesystem │
└─────────────────────────────────────────────────────────────┘
Network configuration:
# Display networks
docker network ls
# Create new network
docker network create my-network
# Connect container to network
docker run -d --network my-network --name webserver nginx
c) Container Orchestration
Container orchestration helps you manage and coordinate many containers efficiently. Think of it like a conductor leading a large orchestra.
┌─────────── Container Orchestration (Kubernetes) ────────────┐
│ Control Plane (Master Node): │
│ ├── API Server (Central Endpoint) │
│ ├── Scheduler (Pod Distribution on Nodes) │
│ └── Controller Manager (Desired vs Actual State) │
├─────────────────────────────────────────────────────────────┤
│ Worker Nodes: │
│ ├── Kubelet (Node Agent) & Container Runtime (CRI) │
│ └── Kube-Proxy (Network Routing & Service Load Balancing) │
├─────────────────────────────────────────────────────────────┤
│ Container Lifecycle: │
│ [ Image ] ───> [ Container ] ───> [ Pod ] ───> [ Service ] │
│ Template Runtime Unit Network │
└─────────────────────────────────────────────────────────────┘
🔧 Practical example: Docker Compose multi-container setup
# Install Docker Compose
sudo apt install docker-compose
# Create simple Compose file
cat << EOF > docker-compose.yml
version: '3'
services:
web:
image: nginx
ports:
- "80:80"
db:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: example
EOF
# Start containers
docker-compose up -d
d) Advanced Container Orchestration
┌─────────── Kubernetes Deployment Hierarchy ─────────────────┐
│ Deployment (Declarative Application Definition) │
│ │ │
│ └── ReplicaSet (Manages Pod Instances and Scaling) │
│ │ │
│ └── Pod 1..N (Smallest Deployable Unit) │
│ │ │
│ └── Container (App Process & Isolation) │
└─────────────────────────────────────────────────────────────┘
🔧 Practical example:
# Kubernetes cluster status
kubectl get nodes
kubectl get pods --all-namespaces
# Create deployment
kubectl create deployment web-app --image=nginx:latest --replicas=3
# Create service
kubectl expose deployment web-app --port=80 --type=LoadBalancer
e) Container Security
Container security is a critical aspect that you as an administrator must understand and implement.
┌─ Container Security Layers ─────────────────────────────────┐
│ - Trusted Sources │
│ - Vulnerability Scanning │
│ - Image Updates │
├─────────── Runtime Security ────────────────────────────────┤
│ - Minimize Privileges │
│ - Limit Resources │
│ - Network Isolation │
├─────────── Host Security ───────────────────────────────────┤
│ - System Updates │
│ - Access Control │
│ - Monitoring │
└─────────────────────────────────────────────────────────────┘
Basic security measures:
# Do not run containers as root
docker run --user 1000:1000 nginx
# Limit resources
docker run --memory=512m --cpus=1 nginx
# Restrict privileges
docker run --security-opt=no-new-privileges nginx
Best practices for container security:
- Use only trusted base images
- Perform regular security updates
- Scan container images for vulnerabilities
- Minimize network access
- Do not store sensitive data in containers
Advanced security concepts
As an administrator, you must operate containers securely. Here are the most important security aspects:
┌─ Container Security Layers ─────────────────────────────────┐
│ - Application │
│ - Libraries │
│ - Configuration │
├─────────── Isolation ───────────────────────────────────────┤
│ - Network │
│ - Processes │
│ - Filesystem │
├─────────── Host System ─────────────────────────────────────┤
│ - Kernel │
│ - Resources │
│ - Access Rights │
└─────────────────────────────────────────────────────────────┘
Securing containers:
# Run containers without root privileges
docker run --user 1000:1000 nginx
# Limit resources
docker run --memory=512m --cpus=1 nginx
# Restrict capabilities
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx
Best practices for container security:
- Use minimal base images
- Regular security updates
- No sensitive data in images
- Restrict network access
- Monitor containers
g) Container Monitoring
Container monitoring is an essential part of container operations. Proactive monitoring enables early detection of performance bottlenecks and potential problems.
┌─────────── Container Monitoring & Workflow ─────────────────┐
│ Monitored Areas: │
│ - Resources: CPU, RAM, Disk-I/O, Network Traffic │
│ - Logs & Status: Stdout/Stderr, Health Checks, Liveness │
├─────────────────────────────────────────────────────────────┤
│ Monitoring Workflow: │
│ │
│ [ Data ] ──> [ Collect ] ──> [ Analyze ] ──> [ Alert ] │
│ Container Prometheus Grafana/Trends Ops-Team │
└─────────────────────────────────────────────────────────────┘
🔧 Practical example: Container monitoring commands
# Basic container information
docker ps
docker stats
# Detailed container information
docker inspect container_name
# Display container logs
docker logs container_name
# Real-time resource usage
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
h) Container Best Practices
Professional container management requires a well-thought-out concept for security and efficiency. The following best practices have proven effective in practice.
┌─ Container Best Practices ──────────────────────────────────┐
│ - Minimal Base Images │
│ - Regular Updates │
│ - Least Privilege │
├─────────── Performance ─────────────────────────────────────┤
│ - Resource Limits │
│ - Multi-Stage Builds │
│ - Optimize Cache │
├─────────── Management ──────────────────────────────────────┤
│ - Clear Naming Convention │
│ - Versioning │
│ - Documentation │
└─────────────────────────────────────────────────────────────┘
Security best practices:
# Use minimal base image
FROM alpine:latest
# Run as non-root user
USER nobody
# Limit resources
docker run --memory=512m --cpus=1 --security-opt=no-new-privileges my-app
Performance best practices:
# Multi-stage build example
FROM node:alpine AS builder
WORKDIR /app
COPY . .
RUN npm install && npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
3. Management best practices:
- Use clear image tags
- Regularly update containers
- Set up logging and monitoring
- Implement backup strategies
2. LXC and LXD
LXC (Linux Containers) and LXD offer a system-near virtualization solution that is particularly suitable for server environments. Unlike Docker, which specializes in application containers, LXC/LXD enables running complete Linux systems in an isolated environment.
┌─────────── System Container vs. App Container ──────────────┐
│ LXC/LXD (System Container): │
│ - Behaves like a lean VM without hypervisor overhead │
│ - Own init system (systemd) & multi-process operation │
├─────────────────────────────────────────────────────────────┤
│ Docker (App Container): │
│ - Caps exactly one application / one microservice task │
│ - Ephemeral lifecycle, stateless and stateless │
├─────────────────────────────────────────────────────────────┤
│ Architecture Comparison: │
│ │
│ ┌── LXC / LXD (System) ──┐ ┌── Docker (Application) ──┐ │
│ │ Full OS Image │ │ Individual Application │ │
│ │ Own systemd Services │ vs │ Only App Dependencies │ │
│ │ Multi-User / SSH Login │ │ A Single PID-1 Task │ │
│ └────────────────────────┘ └──────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
🔧 Practical example: Setting up LXC/LXD system containers
LXC/LXD containers offer a resource-saving alternative to classic virtual machines. Unlike full VMs, these containers share the host system's kernel, enabling more efficient use of available resources.
┌─ Container Structure ───────────────────────────────────────┐
│ Linux Kernel & Operating System │
│ │
│ ┌─── LXC Container 1 ──┐ │
│ │ Filesystem │ │
│ │ Network │ │
│ │ Processes │ │
│ └──────────────────────┘ │
│ │
│ ┌─── LXC Container 2 ──┐ │
│ │ Filesystem │ │
│ │ Network │ │
│ │ Processes │ │
│ └──────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Installation and first steps:
┌─ Installation Dependencies ─────────────────────────────────┐
│ - LXD Daemon │
│ - LXC Libraries │
│ - LXC Tools │
├─────────── Automatic ───────────────────────────────────────┤
│ - liblxc1 │
│ - lxcfs │
│ - lxc-common │
└─────────────────────────────────────────────────────────────┘
# Install LXD
sudo apt install lxd
# This automatically installs:
# - liblxc1 (LXC libraries)
# - lxc-common (shared LXC files)
# - lxcfs (LXC filesystem)
# Initialize LXD
sudo lxd init
# Follow the wizard for:
# - Storage backend (dir or zfs)
# - Network configuration
# - IPv4/IPv6 settings
# Create first container
lxc launch ubuntu:22.04 my-container
Container management:
# Display container status
lxc list
# Enter container
lxc exec my-container -- bash
# Stop/start container
lxc stop my-container
lxc start my-container
b) Container Configuration
LXC/LXD container configuration enables precise adjustment of resources and functions. A well-thought-out configuration is crucial for the performance and security of the container environment.
┌─ Container Configuration ───────────────────────────────────┐
│ - CPU Limits │
│ - RAM Limits │
│ - Disk Quotas │
├─────────── Network ─────────────────────────────────────────┤
│ - Interfaces │
│ - IP Addresses │
│ - Firewall │
├─────────── Storage ─────────────────────────────────────────┤
│ - Volumes │
│ - Mounts │
│ - Snapshots │
└─────────────────────────────────────────────────────────────┘
Resource configuration:
# Set CPU limits
lxc config set mycontainer limits.cpu 2
# Set RAM limits (2GB)
lxc config set mycontainer limits.memory 2GB
# Disk quota (20GB)
lxc config set mycontainer limits.disk.size 20GB
Network configuration:
# Add network interface
lxc config device add mycontainer eth0 nic \
name=eth0 \
nictype=bridged \
parent=lxdbr0
# Set static IP
lxc config device set mycontainer eth0 ipv4.address 192.168.1.100
c) LXC/LXD Container Security
LXC/LXD container security is a critical aspect in professional operations. A well-thought-out security concept protects both containers and the host system from unauthorized access and potential security risks.
┌─ Security Layers ───────────────────────────────────────────┐
│ - Unprivileged │
│ - Privileged │
│ - Root Restrictions │
├─────────── Host ────────────────────────────────────────────┤
│ - AppArmor/SELinux │
│ - Resource Limits │
│ - Network Isolation │
├─────────── Storage ─────────────────────────────────────────┤
│ - Encryption │
│ - Quota │
│ - Snapshots │
└─────────────────────────────────────────────────────────────┘
Unprivileged containers (recommended):
┌─────────── Unprivileged ────────────────────────────────────┐
│ - Restricted Privileges │
│ - Safer │
│ - Default Recommendation │
└─────────────────────────────────────────────────────────────┘
# Create container with security settings
lxc launch ubuntu:22.04 secure-container \
-c security.privileged=false \
-c security.nesting=false \
-c linux.kernel_modules=false
# Set resource limits
lxc config set secure-container limits.memory 2GB
lxc config set secure-container limits.cpu 2
Privileged container
┌─ Container Privileges ──────────────────────────────────────┐
│ - Full system access │
│ - Dangerous! │
│ - Only for special cases │
└─────────────────────────────────────────────────────────────┘
# Create privileged container
lxc launch ubuntu:22.04 priv-container \
-c security.privileged=true \
-c security.nesting=true \
-c linux.kernel_modules=true
# Check container status
lxc config show priv-container | grep security
IMPORTANT: Security risks
- Privileged containers have full system access
- Can access host hardware
- Can load kernel modules
- Should only be used in test environments
- Never use in production environments
Configure AppArmor profiles:
# Check AppArmor status
sudo aa-status
# Container with specific profile
lxc config set secure-container \
lxc.apparmor.profile=lxc-container-default-cgns
# Create custom profile
sudo nano /etc/apparmor.d/lxc-secure
Apply Seccomp filters:
# Enable default Seccomp filter
lxc config set secure-container \
lxc.seccomp.profile=default
# Advanced restrictions
lxc config set secure-container \
security.syscalls.blacklist=mount,umount2
d) Encryption, Quota, and Snapshots
┌─ Container Management ──────────────────────────────────────┐
│ - LUKS Encryption │
│ - Storage Pool Security │
│ - Access Protection │
├─────────── Quota ───────────────────────────────────────────┤
│ - Storage Space Limits │
│ - Resource Control │
│ - Monitoring │
├─────────── Snapshots ───────────────────────────────────────┤
│ - Snapshots │
│ - Backup & Restore │
│ - Versioning │
└─────────────────────────────────────────────────────────────┘
Container encryption:
# Encrypt storage pool with LUKS
lxc storage create encrypted_pool dir \
source=/encrypted/pool \
security.luks=true
# Create container in encrypted pool
lxc launch ubuntu:22.04 secure-container \
-s encrypted_pool
Quota management:
# Set storage space limit
lxc config set my-container limits.disk.size 10GB
# Set RAM limit
lxc config set my-container limits.memory 2GB
Snapshot management:
# Create snapshot
lxc snapshot my-container snap01
# Restore snapshot
lxc restore my-container snap01
# List snapshots
lxc info my-container
e) Best Practices for LXC/LXD
- Create regular snapshots
- Use clear naming conventions
- Document container configurations
- Implement monitoring strategy
- Develop and test backup plan
Exercise
Setting Up a Virtualization Environment
Scenario: You are a junior system administrator at a mid-sized company. Your task is to set up a test environment for the development department.
┌─ Requirements ──────────────────────────────────────────────┐
│ - Ubuntu Server 22.04 LTS │
│ - 4GB RAM, 2 vCPUs │
│ - 50GB Storage │
├─────────── Test Server ─────────────────────────────────────┤
│ - Debian 12 │
│ - 2GB RAM, 1 vCPU │
│ - 20GB Storage │
├─────────── Monitoring ──────────────────────────────────────┤
│ - LXC Container │
│ - Prometheus + Grafana │
│ - 1GB RAM │
└─────────────────────────────────────────────────────────────┘
Tasks:
- VM Setup
- Create both VMs with the specified specifications
- Configure network for communication between VMs
- Create snapshots after basic installation
- Backup Configuration
- Set up daily backups
- Implement snapshot rotation (max. 7 snapshots)
- Test recovery
- Container Setup
- Create LXC containers for monitoring
- Configure network access
- Implement basic security
Possible solution:
VM Setup:
# Create development server
virt-install \
--name dev-server \
--memory 4096 \
--vcpus 2 \
--disk size=50 \
--os-variant ubuntu22.04 \
--network bridge=virbr0 \
--location 'http://archive.ubuntu.com/ubuntu/dists/jammy/main/installer-amd64/'
# Create test server
virt-install \
--name test-server \
--memory 2048 \
--vcpus 1 \
--disk size=20 \
--os-variant debian12 \
--network bridge=virbr0
# Create snapshots
virsh snapshot-create-as dev-server snap01 "After installation"
virsh snapshot-create-as test-server snap01 "After installation"
Backup Configuration:
# Create backup script
cat << 'EOF' > /usr/local/bin/vm-backup.sh
#!/bin/bash
# Create snapshot
virsh snapshot-create-as dev-server backup-$(date +%Y%m%d)
# Delete old snapshots (older than 7 days)
for snap in $(virsh snapshot-list dev-server --name | grep backup- | sort -r | tail -n +8); do
virsh snapshot-delete dev-server $snap
done
EOF
# Make backup script executable
chmod +x /usr/local/bin/vm-backup.sh
# Set up cron job
echo "0 2 * * * /usr/local/bin/vm-backup.sh" | sudo crontab -
Container Setup:
# Create LXC container
lxc launch ubuntu:22.04 monitoring
# Configure container
lxc config set monitoring limits.memory 1GB
lxc config set monitoring limits.cpu 1
# Configure security
lxc config set monitoring security.privileged false
lxc config set monitoring security.nesting false
Command Reference (Cheatsheet)
| Command / Syntax | Category | Function & Description |
|---|---|---|
kvm-ok |
Hardware | Checks hardware virtualization support (VT-x/AMD-V) |
virsh list --all |
VM Status | Shows all virtual machines (running & stopped) |
virsh start <VM> |
VM Control | Starts a virtual machine |
virsh shutdown <VM> |
VM Control | Gracefully shuts down guest OS via ACPI |
virsh destroy <VM> |
VM Control | Forces immediate shutdown (hard power-off) |
virsh autostart <VM> |
Autostart | Enables automatic VM start on host boot |
virt-install --name ... |
Creation | Creates and installs new VM via command line |
qemu-img create -f qcow2 disk.qcow2 50G |
Storage | Creates dynamically growing QCOW2 disk image |
virsh snapshot-create-as <VM> snap1 |
Snapshots | Creates consistent snapshot of a VM |
virsh snapshot-revert <VM> snap1 |
Snapshots | Reverts VM to defined snapshot state |
virt-top |
Monitoring | Real-time CPU and RAM monitoring for all running VMs |
virsh dumpxml <VM> > vm.xml |
Backup | Saves XML hardware configuration of a VM |
Further Resources
| Resource | Description |
|---|---|
| Libvirt Virtualization API Documentation | Official Libvirt and virsh reference documentation |
| QEMU System Emulation Guide | Official user manual for QEMU and KVM |
| Ubuntu 26.04: Docker installieren & absichern | Practical introduction to modern container virtualization |
| Linux Administration #7: System Security | Previous part: SSH hardening, firewalls, Fail2ban & LUKS |
| Befehlszeilenprozessor in Linux | Fundamental knowledge about shells, I/O streams, and pipes |
Conclusion
Mastering virtualization technologies and VM management forms the crowning completion of our Linux system administration course. By using KVM, QEMU, and Libvirt, you transform physical hardware into highly flexible, isolated, and highly available data center structures. Combined with containers, automated backups, and solid resource monitoring, you are well-equipped to professionally operate demanding server landscapes.
💡 Practical tip: For production VMs, always use QCOW2 format with preallocation metadata (
qemu-img create -f qcow2 -o preallocation=metadata disk.qcow2 100G) or LVM thin pools. This achieves near bare-metal I/O performance with full snapshot and cloning flexibility.
In the next module of our administration course, we turn to continuous system monitoring and performance analysis:
👉 Next up: Linux Administration #9: System Monitoring and Performance Monitoring
👉 Course Overview: All Linux Administration Articles & Modules