Introduction
The announcement of CentOS Linux 8’s early end-of-life in December 2021 and the shift to CentOS Stream marked a significant change in the enterprise Linux ecosystem. This comprehensive guide explores the differences between Rocky Linux and CentOS, provides detailed migration strategies, and offers step-by-step instructions for organizations transitioning from CentOS to Rocky Linux.
Understanding the CentOS Landscape Changes
The CentOS Evolution
CentOS (Community Enterprise Operating System) has undergone significant changes:
-
CentOS Linux (Traditional)
- Point release distribution
- Binary compatible with RHEL
- Stable, predictable releases
- Long-term support cycles
-
CentOS Stream
- Rolling release model
- Development branch of RHEL
- Continuous updates
- Shorter support lifecycle
-
End-of-Life Timeline
- CentOS 7: June 30, 2024
- CentOS 8: December 31, 2021
- CentOS Stream 8: May 31, 2024
- CentOS Stream 9: Ongoing
Why Rocky Linux?
Rocky Linux emerged as a direct response to CentOS changes:
# Key advantages of Rocky Linux:
# 1. Bug-for-bug compatible with RHEL
# 2. Community-driven development
# 3. Enterprise-grade stability
# 4. Long-term support commitment
# 5. Free and open source
# Check Rocky Linux information
cat /etc/rocky-release
cat /etc/os-release
Rocky Linux vs CentOS Comparison
Technical Differences
Feature | CentOS Linux | CentOS Stream | Rocky Linux |
---|---|---|---|
Release Model | Point Release | Rolling | Point Release |
RHEL Relationship | Downstream | Upstream | Downstream |
Stability | High | Moderate | High |
Enterprise Ready | Yes | Development | Yes |
Support Lifecycle | 10 years | ~5 years | 10 years |
Update Frequency | Periodic | Continuous | Periodic |
Compatibility Analysis
# Check system compatibility
#!/bin/bash
echo "=== System Compatibility Check ==="
# Kernel version
echo "Kernel: $(uname -r)"
# Architecture
echo "Architecture: $(uname -m)"
# SELinux status
echo "SELinux: $(getenforce)"
# Package count
echo "Installed packages: $(rpm -qa | wc -l)"
# Repository configuration
echo "Configured repositories:"
yum repolist
# Third-party software
echo "Third-party packages:"
rpm -qa --qf '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH} (%{VENDOR})\n' | grep -v "Red Hat\|CentOS"
Pre-Migration Assessment
System Inventory
# Create comprehensive system inventory
#!/bin/bash
INVENTORY_DIR="/root/migration-inventory"
mkdir -p $INVENTORY_DIR
# System information
echo "=== Gathering System Information ==="
# Hardware inventory
dmidecode > $INVENTORY_DIR/hardware.txt
lscpu > $INVENTORY_DIR/cpu.txt
free -h > $INVENTORY_DIR/memory.txt
df -h > $INVENTORY_DIR/disk.txt
lsblk > $INVENTORY_DIR/block-devices.txt
# Network configuration
ip addr > $INVENTORY_DIR/ip-addresses.txt
ip route > $INVENTORY_DIR/routes.txt
ss -tulpn > $INVENTORY_DIR/listening-ports.txt
firewall-cmd --list-all > $INVENTORY_DIR/firewall.txt
# Package inventory
rpm -qa | sort > $INVENTORY_DIR/installed-packages.txt
yum history > $INVENTORY_DIR/yum-history.txt
# Service inventory
systemctl list-units --type=service --all > $INVENTORY_DIR/services.txt
systemctl list-unit-files --type=service > $INVENTORY_DIR/service-files.txt
# Custom configurations
find /etc -name "*.conf" -o -name "*.cfg" | sort > $INVENTORY_DIR/config-files.txt
# Create summary report
cat > $INVENTORY_DIR/summary.txt << EOF
System Inventory Summary
Generated: $(date)
Hostname: $(hostname)
Kernel: $(uname -r)
CentOS Version: $(cat /etc/centos-release)
Total Packages: $(rpm -qa | wc -l)
Active Services: $(systemctl list-units --type=service --state=active | wc -l)
Disk Usage: $(df -h / | tail -1 | awk '{print $3 " / " $2 " (" $5 " used)"}')
EOF
echo "Inventory saved to: $INVENTORY_DIR"
Application Compatibility Testing
# Test application compatibility
#!/bin/bash
echo "=== Application Compatibility Check ==="
# Check for known incompatibilities
check_compatibility() {
local app=$1
if command -v $app >/dev/null 2>&1; then
echo "$app: $(which $app) - $($app --version 2>&1 | head -1)"
else
echo "$app: Not installed"
fi
}
# Common applications
apps=(
"httpd" "nginx" "mysql" "mariadb" "postgresql"
"php" "python" "java" "nodejs" "docker"
"kubernetes" "ansible" "git" "gcc" "make"
)
for app in "${apps[@]}"; do
check_compatibility $app
done
# Check for proprietary software
echo -e "\nProprietary Software:"
rpm -qa --qf '%{NAME} (%{VENDOR})\n' | grep -v "CentOS\|Red Hat" | sort -u
# Check kernel modules
echo -e "\nCustom Kernel Modules:"
lsmod | grep -v "^Module" | awk '{print $1}' | while read module; do
modinfo $module 2>/dev/null | grep -E "^filename:|^author:" | grep -v kernel
done
Migration Methods
Method 1: In-Place Migration (CentOS 8 to Rocky Linux 8)
#!/bin/bash
# In-place migration script for CentOS 8 to Rocky Linux 8
# Ensure running as root
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root"
exit 1
fi
# Create backup point
echo "Creating system backup metadata..."
mkdir -p /root/centos-backup
rpm -qa | sort > /root/centos-backup/installed-packages.txt
cp -r /etc/yum.repos.d /root/centos-backup/
# Download migration script
echo "Downloading Rocky Linux migration script..."
curl -O https://raw.githubusercontent.com/rocky-linux/rocky-tools/main/migrate2rocky/migrate2rocky.sh
chmod +x migrate2rocky.sh
# Verify script
echo "Verifying migration script..."
if ! grep -q "Rocky Linux" migrate2rocky.sh; then
echo "Error: Invalid migration script"
exit 1
fi
# Pre-migration checks
echo "Running pre-migration checks..."
./migrate2rocky.sh -c
# Confirm migration
read -p "Continue with migration? (yes/no): " confirm
if [[ $confirm != "yes" ]]; then
echo "Migration cancelled"
exit 0
fi
# Run migration
echo "Starting migration to Rocky Linux..."
./migrate2rocky.sh -r
# Post-migration verification
if [[ -f /etc/rocky-release ]]; then
echo "Migration successful!"
cat /etc/rocky-release
else
echo "Migration may have failed. Please check system status."
fi
Method 2: Side-by-Side Migration
#!/bin/bash
# Side-by-side migration preparation script
BACKUP_DIR="/backup/centos-migration"
mkdir -p $BACKUP_DIR
echo "=== Preparing for Side-by-Side Migration ==="
# 1. Backup critical data
echo "1. Backing up critical data..."
# System configurations
tar -czf $BACKUP_DIR/etc-backup.tar.gz /etc
tar -czf $BACKUP_DIR/home-backup.tar.gz /home
# Database dumps
if systemctl is-active mariadb >/dev/null 2>&1; then
echo "Backing up MariaDB databases..."
mysqldump --all-databases > $BACKUP_DIR/all-databases.sql
fi
if systemctl is-active postgresql >/dev/null 2>&1; then
echo "Backing up PostgreSQL databases..."
sudo -u postgres pg_dumpall > $BACKUP_DIR/postgresql-all.sql
fi
# 2. Document current configuration
echo "2. Documenting system configuration..."
# Network configuration
cp /etc/sysconfig/network-scripts/ifcfg-* $BACKUP_DIR/ 2>/dev/null
ip addr > $BACKUP_DIR/ip-configuration.txt
ip route > $BACKUP_DIR/routes.txt
# Service configuration
systemctl list-unit-files --state=enabled > $BACKUP_DIR/enabled-services.txt
# Firewall rules
firewall-cmd --list-all-zones > $BACKUP_DIR/firewall-zones.txt
# 3. Export application data
echo "3. Creating application migration checklist..."
cat > $BACKUP_DIR/migration-checklist.txt << 'EOF'
Side-by-Side Migration Checklist
Pre-Migration:
[ ] Full system backup completed
[ ] Database backups verified
[ ] Application data exported
[ ] Network configuration documented
[ ] DNS records documented
[ ] SSL certificates backed up
[ ] Custom scripts backed up
[ ] Third-party repositories noted
Rocky Linux Installation:
[ ] Install Rocky Linux on new system
[ ] Configure base network settings
[ ] Update system packages
[ ] Configure time/NTP
[ ] Set up base security
Data Migration:
[ ] Restore user accounts
[ ] Restore home directories
[ ] Import databases
[ ] Copy application data
[ ] Restore custom configurations
[ ] Install required packages
[ ] Configure services
Testing:
[ ] Verify all services start
[ ] Test application functionality
[ ] Verify database connectivity
[ ] Check log files for errors
[ ] Test user access
[ ] Verify backup procedures
Cutover:
[ ] Schedule maintenance window
[ ] Stop services on old system
[ ] Final data sync
[ ] Update DNS records
[ ] Switch traffic to new system
[ ] Monitor for issues
Post-Migration:
[ ] Monitor system performance
[ ] Check all log files
[ ] Verify backups are working
[ ] Update documentation
[ ] Plan old system decommission
EOF
echo "Migration preparation complete. Files saved to: $BACKUP_DIR"
Method 3: CentOS 7 to Rocky Linux 8 Migration
#!/bin/bash
# CentOS 7 to Rocky Linux 8 migration guide generator
cat > centos7-to-rocky8-migration.md << 'EOF'
# CentOS 7 to Rocky Linux 8 Migration Guide
## Overview
Direct in-place upgrade from CentOS 7 to Rocky Linux 8 is not supported.
Use the side-by-side migration method.
## Step 1: System Analysis
```bash
# Analyze CentOS 7 system
#!/bin/bash
echo "=== CentOS 7 System Analysis ==="
# Check for deprecated features
echo "Checking for deprecated features..."
# Network scripts (deprecated in RHEL 8)
if ls /etc/sysconfig/network-scripts/ifcfg-* >/dev/null 2>&1; then
echo "WARNING: Network scripts found (deprecated in RHEL 8)"
echo "Migration to NetworkManager required"
fi
# Python 2 dependencies
echo "Python 2 packages (require migration to Python 3):"
rpm -qa | grep -E "^python2?-" | grep -v python3
# Deprecated packages
echo "Checking for deprecated packages..."
for pkg in ntp iptables-services xinetd tcp_wrappers; do
rpm -q $pkg >/dev/null 2>&1 && echo "Found deprecated: $pkg"
done
Step 2: Application Inventory
# Create detailed application inventory
#!/bin/bash
# Web servers
echo "Web Servers:"
systemctl status httpd nginx 2>/dev/null | grep -E "Active:|Main PID:"
# Databases
echo -e "\nDatabases:"
systemctl status mariadb mysql postgresql mongodb 2>/dev/null | grep -E "Active:|Main PID:"
# Programming languages
echo -e "\nProgramming Languages:"
for lang in python perl ruby php java node; do
which $lang >/dev/null 2>&1 && echo "$lang: $($lang --version 2>&1 | head -1)"
done
# Custom applications
echo -e "\nCustom Applications:"
find /opt /usr/local -type f -executable 2>/dev/null | head -20
Step 3: Migration Planning
Key Changes from CentOS 7 to Rocky Linux 8:
-
System Changes
- Systemd updates
- NetworkManager by default
- Firewalld enhancements
- New kernel features
-
Package Changes
- Python 3 as default
- PHP 7.2+ versions
- MariaDB 10.3+
- Updated development tools
-
Security Changes
- Enhanced SELinux policies
- Crypto policies
- Updated TLS defaults
- New security features
Migration Approach:
- Install Rocky Linux 8 on new hardware/VM
- Configure base system to match CentOS 7
- Migrate data and applications
- Test thoroughly
- Plan cutover
- Decommission CentOS 7
EOF
echo “Migration guide created: centos7-to-rocky8-migration.md”
## Post-Migration Tasks
### System Verification
```bash
#!/bin/bash
# Post-migration verification script
echo "=== Rocky Linux Post-Migration Verification ==="
# 1. System identification
echo "1. System Information:"
cat /etc/rocky-release
uname -r
hostname
sestatus
# 2. Repository verification
echo -e "\n2. Repository Configuration:"
dnf repolist
dnf check-update
# 3. Service status
echo -e "\n3. Critical Services Status:"
for service in sshd firewalld NetworkManager; do
echo -n "$service: "
systemctl is-active $service
done
# 4. Network connectivity
echo -e "\n4. Network Connectivity:"
ip addr show | grep -E "^[0-9]+:|inet "
ping -c 1 8.8.8.8 >/dev/null 2>&1 && echo "Internet connectivity: OK" || echo "Internet connectivity: FAILED"
# 5. SELinux verification
echo -e "\n5. SELinux Status:"
getenforce
ausearch -m avc -ts recent 2>/dev/null | tail -5
# 6. Package verification
echo -e "\n6. Package Integrity:"
rpm -Va 2>/dev/null | grep -E "^..5" | head -10
# 7. Log file check
echo -e "\n7. Recent Error Messages:"
journalctl -p err -n 10
# Create verification report
cat > /root/migration-verification-report.txt << EOF
Rocky Linux Migration Verification Report
Generated: $(date)
System: $(cat /etc/rocky-release)
Kernel: $(uname -r)
SELinux: $(getenforce)
Services Active: $(systemctl list-units --type=service --state=active | wc -l)
Failed Services: $(systemctl list-units --type=service --state=failed | wc -l)
Network Interfaces: $(ip link | grep -c "state UP")
Verification Status: $(systemctl is-system-running)
EOF
echo -e "\nVerification report saved to: /root/migration-verification-report.txt"
Updating Applications
#!/bin/bash
# Application update script for Rocky Linux
echo "=== Updating Applications for Rocky Linux ==="
# Update all packages
echo "1. Updating system packages..."
dnf update -y
# Reconfigure services if needed
echo "2. Reconfiguring services..."
# Example: Update PHP configuration
if command -v php >/dev/null 2>&1; then
echo "PHP version: $(php -v | head -1)"
# Update php.ini if needed
if [[ -f /etc/php.ini ]]; then
cp /etc/php.ini /etc/php.ini.backup
# Apply Rocky Linux optimized settings
sed -i 's/^memory_limit = .*/memory_limit = 256M/' /etc/php.ini
sed -i 's/^upload_max_filesize = .*/upload_max_filesize = 64M/' /etc/php.ini
sed -i 's/^post_max_size = .*/post_max_size = 64M/' /etc/php.ini
fi
fi
# Example: Update MariaDB configuration
if systemctl is-active mariadb >/dev/null 2>&1; then
echo "MariaDB version: $(mysql --version)"
# Run mysql_upgrade if needed
mysql_upgrade
fi
echo "3. Rebuilding application caches..."
# Rebuild various caches
ldconfig
mandb
updatedb
echo "Application updates completed"
Troubleshooting Common Issues
Repository Issues
# Fix repository issues
#!/bin/bash
echo "=== Fixing Repository Issues ==="
# Clean repository cache
dnf clean all
# Remove old CentOS repositories if present
find /etc/yum.repos.d -name "*centos*" -type f -exec rm {} \;
# Reset Rocky Linux repositories
dnf install -y rocky-release rocky-repos
# Verify repositories
dnf repolist
# Fix GPG key issues
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial
Package Conflicts
# Resolve package conflicts
#!/bin/bash
echo "=== Resolving Package Conflicts ==="
# Find duplicate packages
package-cleanup --dupes
# Find problems
package-cleanup --problems
# Remove old kernels
package-cleanup --oldkernels --count=2
# Fix broken dependencies
dnf check
dnf autoremove
SELinux Issues
# Fix SELinux contexts
#!/bin/bash
echo "=== Fixing SELinux Contexts ==="
# Relabel filesystem
echo "Setting autorelabel flag..."
touch /.autorelabel
# Fix specific contexts
restorecon -Rv /etc
restorecon -Rv /var
# Check for denials
ausearch -m avc -ts recent
echo "System will relabel on next boot"
Best Practices for Migration
Planning Phase
-
Documentation
- Document current system configuration
- Create network diagrams
- List all critical applications
- Note custom configurations
-
Testing Strategy
- Set up test environment
- Perform trial migrations
- Test all applications
- Validate data integrity
-
Rollback Plan
- Create full backups
- Document rollback steps
- Test restore procedures
- Set go/no-go criteria
Execution Phase
# Migration execution checklist
cat > migration-execution-checklist.txt << 'EOF'
Migration Execution Checklist
Pre-Migration (1 week before):
[ ] Final system backup
[ ] Notify stakeholders
[ ] Freeze changes
[ ] Final testing
Migration Day:
[ ] Start maintenance window
[ ] Take final backup
[ ] Stop application services
[ ] Perform final data sync
[ ] Execute migration
[ ] Verify system basics
[ ] Start services
[ ] Test critical functions
[ ] Monitor for issues
Post-Migration:
[ ] Monitor performance
[ ] Check all logs
[ ] Verify backups
[ ] Document issues
[ ] Update procedures
[ ] Train staff
[ ] Plan optimization
EOF
Enterprise Considerations
Support Options
-
Community Support
- Rocky Linux forums
- IRC channels
- Mailing lists
- Documentation wiki
-
Commercial Support
- Third-party support providers
- Consulting services
- Training programs
- SLA-based support
Compliance and Security
# Security compliance check
#!/bin/bash
echo "=== Security Compliance Check ==="
# Check security policies
echo "1. Crypto Policies:"
update-crypto-policies --show
# Check FIPS mode
echo -e "\n2. FIPS Mode:"
fips-mode-setup --check
# Check audit status
echo -e "\n3. Audit Status:"
systemctl status auditd | grep Active
# Check security updates
echo -e "\n4. Security Updates:"
dnf check-update --security
# Generate compliance report
oscap xccdf eval --profile xccdf_org.ssgproject.content_profile_standard \
--results /tmp/compliance-results.xml \
/usr/share/xml/scap/ssg/content/ssg-rl8-ds.xml
Conclusion
Migrating from CentOS to Rocky Linux requires careful planning and execution. Rocky Linux provides a stable, enterprise-ready alternative that maintains compatibility with RHEL while offering long-term support. Key success factors include:
- Thorough pre-migration assessment
- Comprehensive testing
- Detailed documentation
- Proper backup strategies
- Phased migration approach
- Post-migration validation
With proper planning and the tools provided in this guide, organizations can successfully transition from CentOS to Rocky Linux while maintaining system stability and application functionality.