イメージからのサーバー:DHCP + TFTP + Initrd + OpenVZ

ご挨拶。 多くの場合、大規模なプロジェクトでは、同じソフトウェア構成(読み取り-ルート)を持つ同一のサーバーのかなり大きなセットが使用されます。 多くの場合、これらのマシンの管理者は、同じセットのパッケージ、構成など、対称的な状態に維持する必要があります。 など この問題の解決策の1つとして、ネットワーク経由でそのようなマシンを起動して、それらが共通のルートを持ち、RAMに保持し、保存されたデータ(Webサーバーの場合は/ var / wwwなど)が起動後にマウントされるハードドライブに保存されるようにすることが提案されています。 これについてお話します。

私たちが何をするかについてのいくつかの言葉

私が設定した目標の1つは、最大限のシンプルさです。 したがって、この記事では最小限のツールセットを使用しますが、それら自体はできるだけシンプルに使用できます。 イメージをinitrdに直接パックし、同じTFTPサーバーで発行します。これにより、カーネルとブートローダーが提供されます。
オプションの続きとして、最後のセクションでこのタスクでのOpenVZの使用について説明します-私の意見では、仮想ホストでの作業はchroot環境よりも便利です-特に大規模なサーバーの更新を行う場合(そして簡単なテストに便利です)。
OpenVZを使用することにした場合-(特に複数のホストシステムがある場合は特に)DHCPおよびTFTPサーバーをVZコンテナー内に配置することを検討してください-これにより、メインホストシステムに障害が発生した場合にDHCPサーバーを展開できます。
行きましょう。

DHCP

ここではすべてが簡単です。 dhcpdを使用しました。 デフォルトの構成で、次を入力します。
# dhcpd pxelinux
option space pxelinux;
option pxelinux.magic code 208 = string;
option pxelinux.configfile code 209 = text;
option pxelinux.pathprefix code 210 = text;
option pxelinux.reboottime code 211 = unsigned integer 32;

site-option-space "pxelinux";
option pxelinux.magic f1:00:74:7e;
if exists dhcp-parameter-request-list {
option dhcp-parameter-request-list = concat(option dhcp-parameter-request-list,d0,d1,d2,d3);
}

group
{
option pxelinux.configfile "configs/bla-bla.ru/config"; # pxelinux`a
filename "/var/lib/tftpboot/pxelinux.0"; #
#
host first.bla-bla.ru
{
hardware ethernet 48:5b:39:90:b9:06; #MAC
fixed-address 192.168.0.100;
option host-name "first.bla-bla.ru";
}
#
host second.bla-bla.ru
{
hardware ethernet 48:5b:39:90:b9:07; #MAC
fixed-address 192.168.0.101;
option host-name "second.bla-bla.ru";
}
}

subnet 192.168.0.0 netmask 255.255.255.0 #, dhcp-
{
option routers 192.168.0.1; #
option domain-name-servers 192.168.0.2; #DNS
range 192.168.0.100 192.168.0.150; #
}

deny unknown-clients; #


dhcpdを再起動します。 これで、ネットワーク経由で起動する車が提供されます。

TFTP

TFTPの場合、tftp-hpaが使用されました。 正しく動作するためには、次の行が/etc/xinetd.d/tftpに入力されます(ubuntuで自分でファイルを作成する必要がありました)。

service tftp
{
port = 69
socket_type = dgram
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = /var/lib/tftpboot
disable = no
}


設定からわかるように、ネットワーク経由でマシンをダウンロードするためのすべての適切なものを/ var / lib / tftpbootに保存します。 xinetdを再起動します。 TFTPも準備ができました

ブートローダー(PXELinux)

PXELinuxはSYSLinux`a(おそらくすべてのLinux-CDインストールCDで使用されます)の双子の兄弟ですが、ネットワーク経由でブートするように設計されています。 Ubuntuのnetbootイメージからブートローダーを取得しましたが、他の方法で入手できると思われます。 バイナリ(pxelinux.0)を/ var / lib / tftpboot /に配置します。 デフォルトの設定はpxelinux.cfgサブディレクトリにあり、デフォルトがメインの設定として使用されます(フルパスは/var/lib/tftpboot/pxelinux.cfg/defaultになります)。 ただし、dhcpd構成では、bla-bla.ruグループのサーバーがconfigs / bla-bla.ru / config(フルパス/var/lib/tftpboot/configs/bla-bla.ru/configから構成を選択することを示しました) したがって、必要なディレクトリを作成し、構成に書き込みます。

default linux
timeout 100

label linux
kernel kernels/vmlinuz-2.6.32
append panic=15 initrd=images/bla-bla.ru/current


ご覧のとおり、カーネルはkernelsに保存され、イメージ自体はimages /に保存されます。 もちろん、カーネルのバージョンは後で指定します。 しかし、これらすべては後でですが、今のところは、イメージ自体の制作に従事します。

画像を準備する

先ほど言ったように、画像はinitrdに直接保存されます。 この方法は、SquashFS + UnionFSを使用するよりもはるかに簡単です(後者はカーネルに含まれていないため、後者の慢性的な再コンパイルが必要です)。 そして、より簡単/安全なnfs_root 追加の障害ポイントになる可能性がある追加のサービスは必要ありません。
Ubuntuでイメージを作成しました。Debianでも手順は似ています。 したがって、debootstrapが必要です。 どこかにディレクトリを作成し(/ root / imageにします)、そこにイメージを展開します。 たとえば、Ubuntu Lucid:

debootstrap lucid /root/image

ここでchroot`を実行し、カーネルを(ユニットに)配置します。 chroot`aを終了し、結果のカーネルを/ var / lib / tftpboot / kernels /にドラッグし、前のセクションの設定に入力します。 ちなみに、貴重な場所を占有しないように、環境自体から削除することができます。
おそらく既に理解しているように、この環境は将来のイメージです。 ここで、必要なパッケージを配置し、構成を編集できます。 また、/ etc / fstabを作成する必要があります(それを記入したくない場合でも、そこに/ procを配置します;))とinitファイルをルートに配置する必要があります(それなしでは、カーネルパニックは何らかの理由で意図的でしたが、実行する権利がなく、内容は空でした)。 また、/ etc / network / interfacesにdhcpでIPアドレスの受信を入力することをお勧めします-DHCPサーバーは静的アドレスを発行できます。
これで、画像を組み立てる準備ができました。 しかし、その前に、プロセスの1つの機能について知っておく必要があります: cpio-ハードリンクをパックする方法を知りません 。 つまり、それらを解析しないと、ifup、ifdown、mkfs、その他のファイルなどのユーティリティが失われます。
この問題を解決するために、Perlでそれらを解析する小さな松葉杖を作成しましコードはこちらです。 このスクリプトにディレクトリ/ルート/イメージをパラメーターとして指定し、そこでリンクを解析します。 次に、環境があるディレクトリ(/ root / image)に移動して、次のように言います:

find | cpio -H newc -o -p > ../bla-bla.ru; gzip -9 ../bla-bla.ru;cp ../bla-bla.ru.gz /var/lib/tftpboot/images/bla-bla.ru/2011-03-16;ln -s /var/lib/tftpboot/images/bla-bla.ru/2011-03-16 /var/lib/tftpboot/images/bla-bla.ru/current

このコマンドは、initrdのようにイメージをパックし、適切な場所に配置し、currentへのリンクを作成します(configで指定されます)。
以上です! ネットワーク経由で起動しようとすると、マシンは作成したイメージから起動します。

Openvz

OpenVZの助けを借りて、生きた画像モデルを作成します。 VZ仮想コンピューターのイメージはツリーの形でディスクに「そのまま」保存されるため、最初に目的に便利です。したがって、それらをパックすると便利です。 私の場合、もう少し進んで、OpenVZコンテナー内にもDHCP + TFTPを収集しました(もちろん、別々に)。
この問題を解決するためにOpenVZも使用したい場合-この仮想化システム(カーネルサポート、vzctl)の操作に必要なすべてを備えたサーバーが既にあると仮定します-幸いなことに、このトピックに関する十分なドキュメントがあります。

仮想マシンを作成します。

vzctl create 100 --hostname model.bla-bla.ru

まだ実行する必要はありません。 プライベートディレクトリの内容全体(デフォルトでは/ var / lib / vz / private / 100、100は作成時に指定されたVEID)を削除し、前の段落で作成したディレクトリツリーをそこに配置します。

すでにネットワーク設定の自動取得をイメージからデプロイされたシステムに入力できている場合-DHCPサーバーの構成を入力してこの仮想マシンのアドレスを発行するのに怠tooにならないでください(コンテナーのMACアドレスは、ホストシステムコンソールからvzctl enterを実行して実行することで確認できます) ifconfig)、そうでなければ、ネットワークなしで放置されるリスクがあります。

以下を開始します。

vzctl start 100

肯定的な結果が得られると、仮想マシンはアドレスのDHCPサーバーにアクセスし、ネットワーク経由で利用可能になります。 これで、イメージを作成する本格的なマシンと同じ方法で作業できます。
イメージを自動的に構築するために、次のように機能する小さなPerlスクリプト作成しました。
  1. ヘッダーでは、「モデル」(イメージを取得する仮想マシン)とdhcpサーバーのVEIDを宣言します。 dhcpサーバーがVZコンテナにない場合は、$ out_pathを修正してください)
  2. スクリプトで指定された各仮想マシンについて、変更時間/ var / lib / apt / extended_statesがチェックされます(このファイルはパッケージのリストが変更されるたびに変更されます-apt-getを介してインストール/更新)、受信したタイムスタンプは/ var /に書き込まれますcache / netboot / number(ディレクトリが存在する必要があります)。
  3. スクリプトキャッシュからのタイムスタンプがチェックされたファイルの変更時間よりも短い場合、仮想マシンは停止します。
  4. 次に、/ var / cache / aptが(スペースを節約するために)クリーンアップされ、cpioイメージが収集されます。その後、仮想マシンが再び起動します。 以前は、ハードリンクを解析する以前のスクリプトが実行されていました。 PATHに記述されているディレクトリにあると考えられており、nb_links_breaker自体と呼ばれています。
  5. 最後の段階では、cpioイメージがgzipによって押され、目的の場所に移動されます(デフォルトでは-/ var / lib / tftpboot / images / virtual_name / dateとcurrentからのリンクが添付されます)。


ご覧のとおり、スクリプトは最も単純であり、必要に応じて、他の変更に対応するように書き換えることができます。 あなたは彼のcronを掛けることができ、彼は必要に応じて画像を収集し、自分でプロセスに従います。

合計

提案されたオプションには2つの明らかなマイナス点があります。RAMディスクを使用するためのRAM消費量と、ハードディスクに比べて起動時間が長い(画像の取得と展開による) 裏側は結果の機能です。イメージをアセンブルすると、数分で新しいサーバーをコミッションする機会が得られ、アセンブルされた各イメージは更新が失敗した場合のロールバックポイントとして機能します。
もちろん、ここでは、ネットワーク経由でブートする機能を備えたinitrdにパッケージ化された基本システムを取得するために必要な一般的な原則と操作についてのみ説明します。 mdadm`a configや、新しいサーバーでディスクをパーティション分割するなどの作業を簡単にする小さなスクリプトなど、さまざまな仕上げのオプションは読者の裁量に任されています。

これが誰かに役立つことを願っています。 ご清聴ありがとうございました。 :)

Source: https://habr.com/ru/post/J115531/


All Articles