COREOS - загрузка по сети
Решил настроить тестовый кластер coreos с загрузкой по сети.
UPDATE: 31-03-2017: Изменил скрипт поиска обновлений CoreOS.
Используемые инструменты:
- домашний сервер CentOS 7
- libvirtd
- coreos 1205
- coreos-ipxe-server
- etcd2
Задача:
- Загрузить тестовый кластер по сети;
- Делать разбивку диска при загрузке;
- Создать нового пользователя и его окружение.
Настройка libvirtd
Все виртуальные машины используют сеть по умолчанию в режиме nat, внес изменения в сеть default, закрепил адреса к макадресам виртуальных машин.
sudo virsh net-edit default
<network>
<name>default</name>
<uuid>4b147bf4-7496-4351-acdb-f957fd20d38c</uuid>
<forward mode='nat'/>
<bridge name='virbr0' stp='on' delay='0'/>
<mac address='52:54:00:05:d1:18'/>
<dns>
<forwarder addr='192.168.10.2'/>
</dns>
<ip address='192.168.122.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.122.100' end='192.168.122.254'/>
<host mac='52:54:00:55:1c:ee' name='a-coreos' ip='192.168.122.2'/>
<host mac='52:54:00:47:51:e4' name='b-coreos' ip='192.168.122.3'/>
<host mac='52:54:00:81:ac:aa' name='c-coreos' ip='192.168.122.4'/>
</dhcp>
</ip>
</network>
Виртуальные машины грузятся только по сети. Ниже конфигурация машины a.coreos
<domain type='kvm'>
<name>a.coreos</name>
<uuid>c6c30f6a-4a1b-4337-8325-c4c2543ad437</uuid>
<memory unit='KiB'>1048576</memory>
<currentMemory unit='KiB'>1048576</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>
<boot dev='network'/>
</os>
<features>
<acpi/>
<apic/>
</features>
<cpu mode='custom' match='exact'>
<model fallback='allow'>Penryn</model>
</cpu>
<clock offset='utc'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
<timer name='hpet' present='no'/>
</clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<pm>
<suspend-to-mem enabled='no'/>
<suspend-to-disk enabled='no'/>
</pm>
<devices>
<emulator>/usr/libexec/qemu-kvm</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='/storage/iscsi/a.coreos.img'/>
<target dev='hda' bus='ide'/>
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
</disk>
<controller type='scsi' index='0' model='virtio-scsi'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</controller>
<controller type='usb' index='0' model='ich9-ehci1'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x7'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci1'>
<master startport='0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0' multifunction='on'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci2'>
<master startport='2'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x1'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci3'>
<master startport='4'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x2'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
<controller type='ide' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
</controller>
<interface type='bridge'>
<mac address='52:54:00:55:1c:ee'/>
<source bridge='virbr0'/>
<model type='virtio'/>
<rom bar='on' file='/usr/share/ipxe/coreos/a/virtio-net.rom'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<serial type='pty'>
<target port='0'/>
</serial>
<console type='pty'>
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<video>
<model type='cirrus' vram='16384' heads='1' primary='yes'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
</memballoon>
</devices>
</domain>
Для каждой виртуальной машины был собран свой образ ipxe для сетевой карты. Вот настройки сетевой карты для a.coreos
<interface type='bridge'>
<mac address='52:54:00:55:1c:ee'/>
<source bridge='virbr0'/>
<model type='virtio'/>
<rom bar='on' file='/usr/share/ipxe/coreos/a/virtio-net.rom'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
Соберем образ ipxe для виртуальной машины a.coreos
cd /usr/src/ipxe/src
cat menu.ipxe
#!ipxe
dhcp
chain http://192.168.122.1:4777?profile=c-coreos
make clean
make EMBED=menu.ipxe bin/virtio-net.rom
mkdir -p /usr/share/ipxe/coreos/{a,b,c}
mv bin/virtio-net.rom /usr/share/ipxe/coreos/a/virtio-net.rom
Coreos-ipxe-server
Я использую coreos-ipxe-server для загрузки по сети конфигурации для coreos-машин
mkdir -p ${GOPATH}/src/github.com/kelseyhightower
cd ${GOPATH}/src/github.com/kelseyhightower
git clone git@github.com:kelseyhightower/coreos-ipxe-server.git
cd ${GOPATH}/src/github.com/kelseyhightower/coreos-ipxe-server
go build .
mkdir -p /opt/coreos-ipxe-server/{configs,images,profiles,sshkeys}
cp coreos-ipxe-server /opt/coreos-ipxe-server
cat <<EOF > /etc/systemd/system/coreos-ipxe-server.service
[Unit]
Description=coreos-ipxe-server service
After=libvirtd.service
[Service]
Type=simple
Environment=COREOS_IPXE_SERVER_BASE_URL=coreos-ipxe.nurm.local:4777
ExecStart=/opt/coreos-ipxe-server/coreos-ipxe-server
KillSignal=SIGINT
Restart=on-failure
RestartSec=30
[Install]
WantedBy=multi-user.target
EOF
systemctl enable coreos-ipxe-server
systemctl start coreos-ipxe-server
Время от времени нужно проверять текущую версию Coreos. я написал небольшой скрипт, который:
- проверяет текущую версию на сайте;
- изменяет версии во всех профайлах;
- скачивает последние версии на сервер.
Закинул данный файл в /etc/cron.daily/
#!/bin/bash
curl http://stable.release.core-os.net/amd64-usr/current/coreos_production_pxe.sh -o /tmp/coreos-current-version.sh
left=$(cat /tmp/coreos-current-version.sh | grep "VM_NAME" | grep "coreos_production"| cut -d "=" -f 2 | cut -d '-' -f 2)
center=$(cat /tmp/coreos-current-version.sh | grep "VM_NAME" | grep "coreos_production" | cut -d "=" -f 2 | cut -d '-' -f 3)
right=$(cat /tmp/coreos-current-version.sh | grep "VM_NAME" | grep "coreos_production" | cut -d "=" -f 2 | cut -d '-' -f 4 | sed "s/'//")
CURRENT_RELEASE_VERSION=$(echo ${left}.${center}.${right})
echo ${CURRENT_RELEASE_VERSION}
echo "start circle"
for profile in $(ls /opt/coreos-ipxe-server/profiles); do
USED_RELEASE_VERSION=$(cat /opt/coreos-ipxe-server/profiles/${profile} | jq '.version' | sed 's/\"//g')
echo ${USED_RELEASE_VERSION}
if [ "${USED_RELEASE_VERSION}" != "${CURRENT_RELEASE_VERSION}" ]; then
echo "used release version dont match with current release version from website"
sed -i "s/${USED_RELEASE_VERSION}/${CURRENT_RELEASE_VERSION}/" /opt/coreos-ipxe-server/profiles/${profile}
fi
done
if [ ! -d "/opt/coreos-ipxe-server/images/amd64-usr/${CURRENT_RELEASE_VERSION}" ]; then
mkdir -p /opt/coreos-ipxe-server/images/amd64-usr/${CURRENT_RELEASE_VERSION}
fi
if [ ! -f /opt/coreos-ipxe-server/images/amd64-usr/${CURRENT_RELEASE_VERSION}/coreos_production_pxe.vmlinuz ]; then
curl -o /opt/coreos-ipxe-server/images/amd64-usr/${CURRENT_RELEASE_VERSION}/coreos_production_pxe.vmlinuz http://stable.release.core-os.net/amd64-usr/${CURRENT_RELEASE_VERSION}/coreos_production_pxe.vmlinuz
fi
if [ ! -f /opt/coreos-ipxe-server/images/amd64-usr/${CURRENT_RELEASE_VERSION}/coreos_production_pxe_image.cpio.gz ]; then
curl -o /opt/coreos-ipxe-server/images/amd64-usr/${CURRENT_RELEASE_VERSION}/coreos_production_pxe_image.cpio.gz http://stable.release.core-os.net/amd64-usr/${CURRENT_RELEASE_VERSION}/coreos_production_pxe_image.cpio.gz
fi
Создаем профили для виртуальных машин
[nurmukhamed@corei3 coreos-ipxe-server]$ cat profiles/a-coreos.json
{
"cloud_config": "a-cloud-config",
"rootfstype": "btrfs",
"sshkey": "nurmukhamed",
"version": "1298.6.0"
}
[nurmukhamed@corei3 coreos-ipxe-server]$ cat profiles/b-coreos.json
{
"cloud_config": "b-cloud-config",
"rootfstype": "btrfs",
"sshkey": "nurmukhamed",
"version": "1298.6.0"
}
[nurmukhamed@corei3 coreos-ipxe-server]$ cat profiles/c-coreos.json
{
"cloud_config": "c-cloud-config",
"rootfstype": "btrfs",
"sshkey": "nurmukhamed",
"version": "1298.6.0"
}
Просмотр конфигурации для a-coreos. Что делает данная конфигурация:
- Задает имя сервера;
- Создает нового пользователя nurmukhamed;
- Добавляет пользователя nurmukhamed в группы sudo, docker;
- Задает ssh-ключ для авторизации;
- Создает файл /home/nurmukhamed/.bashrc, где задаются алиасы и полезные утилиты;
- Производит очистку жесткого диска, разбиение диска на два раздела;
- Производит форматирование разделов, подключает разделы к /var/lib/docker, /var/lib/rkt;
- Настраивает сервер для работы с etcd2 сервисом, на сервере CentOS.
#cloud-config
hostname: a-coreos.nurm.local
users:
- name: nurmukhamed
groups:
- sudo
- docker
ssh-authorized-keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDnnMkmWq5JNNn/cEx0WyRO330OAmlvWeVwrite-files:
- path: /home/nurmukhamed/.bashrc
permissions: '0644'
content: |
# .bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
./etc/bashrc
fi
alias systemctl='sudo systemctl'
alias svim='sudo vim'
alias list-units='sudo fleetctl list-units'
alias list-machines='sudo fleetctl list-machines'
alias list-unit-files='sudo fleetctl list-unit-files'
service_del() {
sudo fleetctl stop "$@"
sudo fleetctl unload "$@"
sudo fleetctl destroy "$@"
}
service_add() {
sudo fleetctl submit "$@"
sudo fleetctl load "$@"
sudo fleetctl start "$@"
}
sprunge() {
if [[ $1 ]]; then
curl -F 'sprunge=<-' "http://sprunge.us" <"$1"
else
curl -F 'sprunge=<-' "http://sprunge.us"
fi
}
coreos:
units:
- name: format-ephemeral.service
command: start
content: |
[Unit]
Description=Formats the ephemeral drive
After=dev-sda.device
Requires=dev-sda.device
Before=docker.service
Before=fleet.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/wipefs -f /dev/sda
ExecStart=/usr/sbin/parted -s /dev/sda mklabel gpt
ExecStart=/usr/sbin/parted -s /dev/sda mkpart primary ext4 0 9614
ExecStart=/usr/sbin/parted -s /dev/sda mkpart primary ext4 9615 19229
ExecStart=/usr/sbin/mkfs.ext4 -F /dev/sda1
ExecStart=/usr/sbin/mkfs.ext4 -F /dev/sda2
- name: var-lib-docker.mount
command: start
content: |
[Unit]
Description=Mount ephemeral to /var/lib/docker
Requires=format-ephemeral.service
After=format-ephemeral.service
Before=docker.service
[Mount]
What=/dev/sda1
Where=/var/lib/docker
Type=ext4
- name: var-lib-rkt.mount
command: start
content: |
[Unit]
Description=Mount ephemeral to /var/lib/rkt
Requires=format-ephemeral.service
After=format-ephemeral.service
Before=fleet.service
[Mount]
What=/dev/sda2
Where=/var/lib/rkt
Type=ext4
- name: docker.service
command: start
- name: fleet.service
command: start
fleet:
etcd_servers: "http://coreos-ipxe.nurm.local:2379"
locksmith:
endpoint: "http://coreos-ipxe.nurm.local:2379"
Настройка dnsmasq
cat /etc/dnsmasq.d/addresses.conf
address=/coreos-ipxe.nurm.local/192.168.122.1
address=/a-coreos.nurm.local/192.168.122.2
address=/b-coreos.nurm.local/192.168.122.3
address=/c-coreos.nurm.local/192.168.122.4
srv-host=_etcd-server._tcp.nurm.local,coreos-ipxe.nurm.local,2380,1
srv-host=_etcd-client._tcp.nurm.local,coreos-ipxe.nurm.local,2380,1
Настройка ETCD2
cat /etc/etcd/etcd.conf
# [member]
ETCD_NAME=default
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
#ETCD_WAL_DIR=""
#ETCD_SNAPSHOT_COUNT="10000"
#ETCD_HEARTBEAT_INTERVAL="100"
#ETCD_ELECTION_TIMEOUT="1000"
ETCD_LISTEN_PEER_URLS="http://192.168.122.1:2380"
#ETCD_LISTEN_CLIENT_URLS="http://coreos-ipxe.nurm.local:2379"
#ETCD_MAX_SNAPSHOTS="5"
#ETCD_MAX_WALS="5"
#ETCD_CORS=""
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379,http://0.0.0.0:4001"
#ETCD_ADVERTISE_CLIENT_URLS="http://coreos-ipxe.nurm.local:2379"
#
#[cluster]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://coreos-ipxe.nurm.local:2380"
# if you use different ETCD_NAME (e.g. test), set ETCD_INITIAL_CLUSTER value for this name, i.e. "test=http://..."
#ETCD_INITIAL_CLUSTER="default=http://localhost:2380"
#ETCD_INITIAL_CLUSTER_STATE="new"
#ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-1"
ETCD_ADVERTISE_CLIENT_URLS="http://coreos-ipxe.nurm.local:2379"
#ETCD_DISCOVERY=""
#ETCD_DISCOVERY_SRV="nurm.local"
#ETCD_DISCOVERY_FALLBACK="proxy"
#ETCD_DISCOVERY_PROXY=""
#
#[proxy]
#ETCD_PROXY="off"
#ETCD_PROXY_FAILURE_WAIT="5000"
#ETCD_PROXY_REFRESH_INTERVAL="30000"
#ETCD_PROXY_DIAL_TIMEOUT="1000"
#ETCD_PROXY_WRITE_TIMEOUT="5000"
#ETCD_PROXY_READ_TIMEOUT="0"
#
#[security]
#ETCD_CERT_FILE=""
#ETCD_KEY_FILE=""
#ETCD_CLIENT_CERT_AUTH="false"
#ETCD_TRUSTED_CA_FILE=""
#ETCD_PEER_CERT_FILE=""
#ETCD_PEER_KEY_FILE=""
#ETCD_PEER_CLIENT_CERT_AUTH="false"
#ETCD_PEER_TRUSTED_CA_FILE=""
#
#[logging]
#ETCD_DEBUG="false"
# examples for -log-package-levels etcdserver=WARNING,security=DEBUG
#ETCD_LOG_PACKAGE_LEVELS=""
Настройка ssh-клиента
Также требуется внести изменения в работе ssh-клиента. При каждой загрузке виртуальной машины, сервер coreos генерирует новые ssh-ключи, нужно научить ssh-клиента не обращать на это внимание.
Host a-coreos
Hostname a-coreos.nurm.local
User nurmukhamed
StrictHostKeyChecking no
Host b-coreos
Hostname b-coreos.nurm.local
User nurmukhamed
StrictHostKeyChecking no
Host c-coreos
Hostname c-coreos.nurm.local
User nurmukhamed
StrictHostKeyChecking no
Итоги
Данная конфигурация рабочая, после запуска 3х серверов, получаем рабочий кластер coreos.