Створення свого образу з чистим CentOS 8.1 у хмарі Amazon

Даний посібник є «форком» однойменної. статті про CentOS 5.9, та враховує особливості нової OS. На даний момент AWS Marketplace не має офіційного образу Centos8 від centos.org.

Як відомо, у хмарі Amazon віртуальні інстанси запускаються на основі образів (так звані AMI). Amazon надає велику кількість, також можна використовувати публічні образи, підготовлені сторонніми організаціями, за які хмарний провайдер, природно, ніякої відповідальності не несе. Але іноді потрібний образ чистої системи з потрібними параметрами, якого немає у списку образів.

Тоді єдиний вихід – зробити свій AMI.

В офіційній документації описано спосіб створення "instance store-backed AMI".

Мінус такого підходу полягає в тому, що готовий образ потрібно буде ще й сконвертувати в EBS-backed AMI. Також варто відзначити Cockpit Image Builder. Він дозволить створювати кастомні образи, CLI або WEB графічний інтерфейс користувача режимі, але коли ви вже буде Centos 8.

Про те, як створити свій EBS-backed AMI у хмарі Amazon без проміжних кроків, йтиметься у цій статті.

План дій

  • Підготувати оточення
  • Встановити чисту систему, зробити необхідні налаштування
  • Зробити snapshot (зліпок) диска
  • Зареєструвати AMI

Підготовка оточення

Для наших цілей підійде будь-який офіційний інстанс Centos 7 будь-якого шейпа, хоч t2.micro. Запустити його можна через CLI:

aws ec2 run-instances 
  --image-id ami-4bf3d731 
  --region us-east-1 
  --key-name alpha 
  --instance-type t2.micro 
  --subnet-id subnet-240a8618 
  --associate-public-ip-address 
  --block-device-mappings DeviceName=/dev/sda1,Ebs={VolumeSize=8} 
  --block-device-mappings DeviceName=/dev/sdb,Ebs={VolumeSize=4}

Команда підніме інстанс VPC, до якої відноситься вказаний subnet-id. Передбачається, що підмережа буде публічна, і SG 'default' дозволяє все.

Тепер залогінимось на інстанс по ssh, оновимо систему, встановимо dnf і перезавантажимося:

sudo yum update -y && sudo yum install -y dnf && sudo reboot

Всі подальші операції виконуватимуться від root.

Встановлення чистого Centos 8.1

Розмітка файлової системи та монтування розділів

DEVICE=/dev/xvdb
ROOTFS=/rootfs
parted -s ${DEVICE} mktable gpt
parted -s ${DEVICE} mkpart primary ext2 1 2
parted -s ${DEVICE} set 1 bios_grub on
parted -s ${DEVICE} mkpart primary xfs 2 100%

mkfs.xfs -L root ${DEVICE}2
mkdir -p $ROOTFS
mount ${DEVICE}2 $ROOTFS

mkdir $ROOTFS/{proc,sys,dev,run}
mount --bind /proc $ROOTFS/proc
mount --bind /sys $ROOTFS/sys
mount --bind /dev $ROOTFS/dev
mount --bind /run $ROOTFS/run

Створення дерева каталогів

Система RPM дозволяє легко та швидко підготувати дерево каталогів майбутньої ОС:

PKGSURL=http://mirror.centos.org/centos/8/BaseOS/x86_64/os/Packages
rpm --root=$ROOTFS --initdb
rpm --root=$ROOTFS -ivh 
  $PKGSURL/centos-release-8.1-1.1911.0.8.el8.x86_64.rpm 
  $PKGSURL/centos-gpg-keys-8.1-1.1911.0.8.el8.noarch.rpm 
  $PKGSURL/centos-repos-8.1-1.1911.0.8.el8.x86_64.rpm

dnf --installroot=$ROOTFS --nogpgcheck --setopt=install_weak_deps=False 
   -y install audit authselect basesystem bash biosdevname coreutils 
   cronie curl dnf dnf-plugins-core dnf-plugin-spacewalk dracut-config-generic 
   dracut-config-rescue e2fsprogs filesystem firewalld glibc grub2 grubby hostname 
   initscripts iproute iprutils iputils irqbalance kbd kernel kernel-tools 
   kexec-tools less linux-firmware lshw lsscsi ncurses network-scripts 
   openssh-clients openssh-server passwd plymouth policycoreutils prefixdevname 
   procps-ng  rng-tools rootfiles rpm rsyslog selinux-policy-targeted setup 
   shadow-utils sssd-kcm sudo systemd util-linux vim-minimal xfsprogs 
   chrony cloud-init 

Останню команду вважаю оптимально виконувати саме так, установкою конкретних пакетів, і обов'язково, ігнорувати рекомендовані пакети.

За бажанням, ви можете використовувати приблизно такий варіант:

dnf --installroot=$ROOTFS groupinstall base core 
    --excludepkgs "NetworkManager*" 
     -e "i*-firmware"

В yum немає --excludepkgs, і раніше доводилося встановлювати групи, а потім видаляти пакети.

Список пакетів та залежних груп можна переглянути командою dnf group info core для групи core.

Кастомізація файлів ОС

Створимо конфіги для мережі, fstab, grub2 та використовуємо інтернальні 169.254 адреси AWS для DNS та NTP.

cat > $ROOTFS/etc/resolv.conf << HABR
nameserver 169.254.169.253
HABR

cat > $ROOTFS/etc/sysconfig/network << HABR
NETWORKING=yes
NOZEROCONF=yes
HABR

cat > $ROOTFS/etc/sysconfig/network-scripts/ifcfg-eth0  << HABR
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=dhcp
HABR

cat > $ROOTFS/etc/fstab << HABR
LABEL=root / xfs defaults,relatime 1 1
HABR

sed -i  "s/cloud-user/centos/" $ROOTFS/etc/cloud/cloud.cfg
echo "server 169.254.169.123 prefer iburst minpoll 4 maxpoll 4" >> $ROOTFS/etc/chrony.conf
sed -i "/^pool /d" $ROOTFS/etc/chrony.conf
sed -i "s/^AcceptEnv/# /" $ROOTFS/etc/ssh/sshd_config

cat > $ROOTFS/etc/default/grub << HABR
GRUB_TIMEOUT=1
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto console=ttyS0,115200n8 console=tty0 net.ifnames=0 biosdevname=0"
GRUB_DISABLE_RECOVERY="true"
GRUB_ENABLE_BLSCFG=true
HABR

Саме тут, у GRUB_CMDLINE_LINUX я рекомендую вказувати selinux=0, для тих, хто все ще боїться SELinux.

Перескладання initramfs в chroot

Після виправлення фалів grub і fstab необхідно виконати перескладання.
Виконуємо оновлення:

KERNEL=$(ls $ROOTFS/lib/modules/) 
chroot $ROOTFS dracut -f -v /boot/initramfs-$KERNEL.img $KERNEL
chroot $ROOTFS grub2-mkconfig -o /boot/grub2/grub.cfg
chroot $ROOTFS grub2-install $DEVICE
chroot $ROOTFS update-crypto-policies --set FUTURE

Тут update-crypto-policies - За бажанням, для параноїків 🙂

Для "прода", можна зробити так:

chroot $ROOTFS fips-mode-setup --enable
chroot $ROOTFS grub2-mkconfig -o /boot/grub2/grub.cfg
chroot $ROOTFS grub2-install $DEVICE

Після завантаження ОС команда update-crypto-policies --show видасть FIPS.

Автозапуск та Чищення сміття

chroot $ROOTFS systemctl enable network.service
chroot $ROOTFS systemctl enable sshd.service
chroot $ROOTFS systemctl enable cloud-init.service
chroot $ROOTFS systemctl mask tmp.mount
dnf --installroot=$ROOTFS clean all
truncate -c -s 0 $ROOTFS/var/log/*.log
rm -rf var/lib/dnf/*
touch $ROOTFS/.autorelabel

autorelabel - Потрібен для автоматичної установки SELinux контексту файлів під час першого завантаження.

Тепер розмонтуємо диск:

sync
umount $ROOTFS/{proc,sys,dev,run}
umount $ROOTFS

Реєстрація AMI

Щоб отримати з ebs-диска ami, потрібно спочатку зробити снапшот диска:

aws ec2 create-snapshot 
    --volume-id vol-09f26eba4c50da110  --region us-east-1 
    --description 'centos-release-8.1-1.1911.0.8 4.18.0-147.5.1 01'

Якийсь час треба буде зачекати. Перевіримо статус за отриманим SnapshotId:

aws ec2   describe-snapshots  --region us-east-1 --snapshot-ids snap-0b665542fc59e58ed

Коли отримаємо "State": "completed", можна зареєструвати AMI і зробити його публічним:

aws ec2 register-image 
    --region us-east-1 
    --name 'CentOS-8.1-1.1911.0.8-minimal' 
    --description 'centos-release-8.1-1.1911.0.8 4.18.0-147.5.1 01' 
    --virtualization-type hvm --root-device-name /dev/sda1 
    --block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs": { "SnapshotId": "snap-0b665542fc59e58ed", "VolumeSize":4,  "DeleteOnTermination": true, "VolumeType": "gp2"}}]' 
    --architecture x86_64 --sriov-net-support simple --ena-support

aws ec2 modify-image-attribute 
    --region us-east-1 
    --image-id ami-011ed2a37dc89e206 
    --launch-permission 'Add=[{Group=all}]'

На цьому все. Тепер можна запускати інстанси.

У такий спосіб можна зробити образ, швидше за все, з будь-яким Linux-дистрибутивом. Принаймні, точно Debian (використовуючи debootstrap для встановлення чистої системи) та RHEL-родини.

ОНОВЛЕННЯ За заявками читачів. Автоматизувати цей процес може Пакувальниктільки Автоматизувати. Тут представлений приклад темплейту.

Джерело: habr.com

Додати коментар або відгук