PXEBOOT/BOOTP/DHCPあたりのことをまとめておく
この辺りはよく使ってる技術なんだけど一回作ってしまうと細かなことは忘れてしまうし、 AWSのようなクラウドサービスを使っていると触れる機会も減ってしまうので、 覚えているうちにまとめておこうと思う。
PXEBOOT
ネットワークカードに搭載されているPXE(Preboot eXecution Environment)機能を使ってプログラムを起動する方法。
起動するプログラムはDHCPサーバとTFTPなどのサーバを組み合わせて配布する。
ネットワークカードにPXEBOOTのための機能が搭載されているものがあれば、BIOSのBOOTをネットワークブートに設定すれば使える。
DHCPはBOOTPの上位互換プロトコルなので、BOOTP的な設定はDHCPサーバの設定に書くこともできる。
DHCP設定にTFTPサーバがどのアドレスかなどの情報を書いておき、クライアントに配布できるが、特に指定がない場合DHCPサーバとTFTPサーバは同じアドレスとみなされる。
TFTP、DHCPサーバともに軽量なサーバなことが多く、同じ物理サーバに設置することもある。
DHCP
PXE対応ネットワークカードは起動時にDHCPでマルチキャストパケットを投げる。
ネットワーク上にDHCPサーバがあれば、パケットに応答しPXEの情報をクライアントに返す。
複数のDHCPサーバが応答する場合、どれが応答するかわからなくなるため同一ネットワークに複数のDHCPサーバと立てないようにしたい。
TFTP
UDPでやりとりするファイル転送用のプロトコル。FTPより単純で認証などない。PXEで実行するイメージを転送する際に使うことができる。
暗号化も特にされていないので ngrep などでパケットを眺めればどういうやり取りがされているか簡単にわかる。
MACアドレスやDHCPで割り当てされたIPアドレスの一部を使って設定ファイルをダウンロードしようとする。これはPXEの仕様。
例えば、 192.168.0.200
をDHCPで割り当てた場合、それぞれのアドレスを16進数に変換した、 C0A800C8
というファイルをリクエストする。
ファイルが見つからなかった場合、1文字短くした C0A800
、 次には2文字短くした C0A8
といったファイルを順にリクエストしてくる。
この仕組みがあるので、サブネットごとに違うアドレスレンジをDHCPサーバが返すことでネットワークごとに違う設定ファイルをクライアントに渡すことができる。
設定ファイルの実体は pxelinux.cfg
と同じ書式のもので、シンボリックリンクで名前だけ用意するのが簡単。
TFTPサーバはセキュリティの都合上、chroot化で実行されることがままあるため、シンボリックリンクを張る際には /
からの絶対パスではなく相対パスで作成しておくのが無難。
DebianでPXEサーバとDHCPサーバとTFTPサーバを作る例
TFTPサーバは tftpd-hpa
、DHCPサーバは isc-dhcp-server
をそれぞれ使う。
apt install tftpd-hpa isc-dhcp-server
TFTPサーバの設定
TFTPサーバの設定は /etc/default/tftp-hpa
だが、対して設定項目もないのでそのまま使ってもよい。
その場合、 /srv/tftp
がTFTPサーバのルートとなり、chrootされた状態でサーバが起動される。
TFTP自体の設定は対してないが、いくつか重要なファイルがある。
/srv/tftp/pxelinux.0
pxelinuxのブートイメージ。後述のDHCPサーバの指定で細かな指定がない場合 filename "pxelinux.0"
はこのパスになる。
/srv/tftp/pxelinux.cfg/
MACアドレスやIPアドレスで設定ファイルを探しに来る場所。該当するMACアドレスやIPアドレスのものがない場合は default
のファイルが読みだされる。
いずれのファイルも見つからない場合、ネットワークブートは失敗に終わる。
DHCPサーバの設定
DHCPサーバの設定は、 /etc/dhcp/dhcpd.conf
でこちらはネットワークに合わせて少し設定が必要になる。
この辺りは単にDHCPの設定になるし、DHCPは家庭LANでもよく使われているので改めて説明の必要もないかもしれない。
allow bootp
と allow booting
あと、 nameserver
の設定、PXEのイメージを配るときの名前 filename
あたりの設定と、ネットワークのサブネット周りをちゃんと見ておく。
DebianのWikiにも設定例があるけど、細かいところはネットワークによって違うので何とも言い難い。
サーバの再起動
設定ができたら、DHCPとTFTPを再起動しておく。最近はsystemdでやる。
動作確認
多分これだけで動く。適当に動作確認して問題なければこのまま使えばいいと思う。終わり。
コミティアいくぞ
— シリル@バンドリフレンズ (@d_cyrill1129) 2017年5月5日
老エンジニアだけど dotfiles を更新したい、だけど慣れた設定書き換えるのって怖くない?辛い...って思ってサボってきた更新をなんとかした話
概略
- 最小のSandbox環境を作る。
/home/$USER
をgit init
してコミット- どうせ Sandbox だし乱暴する
- dotfiles をいい感じに書き換えてセットアップ
- どうせ Sandbox だし乱暴する
- 期待通りの挙動をしない場合、gitの機能で元に戻し、うまくいったらコミット
git clean -df
でだいたいうまくいく
以下詳細をまとめます。
debootstrap + chroot なサンドボックス環境を用意する
前はvagrantで律儀にsnapshotをとって戻して差分を確認していたが、もうちょっと雑にやる方法はないものかと chroot 環境を用意。
DebootstrapはDebianのWikiに細かい説明がある。
stable Debianの最小構成をインストールする
sudo apt-get install debootstrap chroot mkdir -p /tmp/workdir cd /tmp sudo debootstrap stable workdir/ sudo chown -R $USER. workdir
これで /tmp/workdir
にdebianがインストールされる。
chroot する
chroot
するには特権が必要なので少し心が傷むが自分のマシンだからまあいいかと割り切ってsudo chroot
をキメる。
sudo chroot workdir/ /bin/bash
cd /root
これで root シェルが取れる。
Debianの基本セットアップをする
最小構成のDebianでは色々とパッケージが足りなくて辛い気持ちになる。 apt update
すらできないからね。
あと、 proc
とか /dev/pts
とかもないね。まあこのあたりはどこまでそれっぽくするかによるし、いらないセットアップな気もする。
/tmp
が必要なら mkdir /tmp
とでもしておけばいいと思う。 (律儀にtmpfs
をmount
しなくてもいいよね)
echo "deb http://ftp.jp.debian.org/debian/ jessie main contrib non-free deb http://ftp.jp.debian.org/debian/ jessie-updates main contrib deb-src http://ftp.jp.debian.org/debian/ jessie main contrib non-free deb-src http://ftp.jp.debian.org/debian/ jessie-updates main contrib" > /etc/apt/sources.list apt update
apt update
したいので、sources.list
を雑に用意する。(apt-getじゃなくなって久しい)。
あとは適当に必要なパッケージ、zsh
とかtmux
とか好きに入れる。
このあとで使うので git
も入れておく。 git
って以外と依存パッケージが多いねって気持ちになるがまあこんなものかもしれない。
apt install zsh tmux curl git
apt
の幾つかで警告が出ることがあるが、心を痛めつつ無視して先に進める。(サンドボックスは乱暴する)
git管理を始める
ロックに $HOME
で git init
をキメて全ファイルをコミットする。
dotfiles
用のリポジトリが用意してあればそれをclone
しておきそれもコミットする。
cd $HOME git init git clone https://github.com/..../dotfiles git add . git commit -m 'Commit all home files'
これで $HOME
以下のファイルはすべて追跡できるようになった。
dotfilesに乱暴をする
大抵の変更は git commit
の時点まで戻せるので、乱暴に自分の dotfiles
を書き換えてchroot環境でセットアップする。
変更が気に入らなかった場合、 git clean
を使いすべての変更を捨てる。怖い場合は dry-run もある。
git clean -df # git clean -dfn (DRY RUN)
変更がうまくいったら、適当にコミットする。このあたりはコミット粒度とかプログラミングスタイルが試される。各自いい感じにしてほしい。
コミットは chroot 環境の外からキメるのが楽。
git commit
終わりに
基本なまけものなのでこういうのは気が向いたときにしかやらない。
終わったらSandboxなので適当に捨てるといいけど、丁寧に proc
とかを mount
していると rm -rf
したときに寒い感じがする。
技術書展2 に出ます
ところでまったく話は変わりますが、2017/4/9に行われる技術書オンリーイベント「技術書典2」に 「mochi mochi laboratory」さんと合同で参加します。 (TechBooster / 達人出版会 さん主催)
「mochi mochi laboratory」と「ゆきいろパラソル」の合同サークル 「もちもちパラソル」 です。
情報は ゆいしろさんの特設ページと、こっちでも少し情報を流していきます。
もちもちパラソル 技術書典2 特設ページ
技術書典2
進展がありましたら更新します。
最近のこと
シンデレラキャラバンのこずえさん、いつのまにかいなくなってて泣きそう
— シリル@技術書典2 う-01 (@d_cyrill1129) 2017年1月16日
デレステのシンデレラキャラバンの回収は期限付き。忘れないようにしないとこうなります。つらい。
マジかよー・・・ pic.twitter.com/5ycNyapB3u
— シリル@技術書典2 う-01 (@d_cyrill1129) 2017年1月9日
iPhoneのディスプレイ割れてる人は強制交換ペナルティ1万2000円がかかります。やったね。
冬コミ、やっぱりコミケ参加したい欲求が高いということがわかり、技術書典2に出ることにしました。夏も申し込むけど、結局同人ソフトで出ることになる…かな。漫画描けるようになりたい。
真剣にRedisを使ってみようという気持ちになったのでRedisについて知っていることを書く
年末ですね。更新がおろそかになっていたので、たまにはちゃんとした話をしたいなと思い、前々から書こうと思っていたRedisの話を書いてみました。
検証に使用したRedisは3.2ですので、新しくバージョンが変わると以下の話は変わってくるかもしれませんが今のところそのようなことはしばらくなさそうです。
以下長々とRedisを本当に使えるように設定したり調べたり検証したりした内容を書いていきます。
続きを読むMySQL InnoDB memcached pluginを使ってみようとしてやめた話
追記 MySQL 5.7.19か20あたりで取り込まれたパッチにより以下の問題は発生しなくなりました。つまりはバグでした。
InnoDB memcached pluginはMySQL 5.6から搭載された機能で、Memcacheプロトコルを使ってInnoDBにデータを読み書きできる便利機能です。 簡単なプロトコルなためSQLより高速に動作する点、InnoDBに記録できる点、MySQLのレプリケーションが利用できる点など、 うまく使えば便利な仕組みですが、結論を先に書いてしまうと使えなかったという話をします。
使えなかった理由
MySQL memcached pluginを使ったInnoDBへのインターフェイスが使えなかった理由はクラッシュが多発するためです。
高速な動作、レプリケーション機能などはうまく動作しているのですが、
しばらく動作させていると get 操作の際に SIGABRT
となりMySQLが動作停止します。
Program received signal SIGABRT, Aborted. [Switching to Thread 0x7ffcf2ffd700 (LWP 722)] 0x00007ffff67e2067 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 ...
MySQL5.7.14での実行結果ですが、5.6.32, 5.7.15, 8.0 でも同じように停止します。 アサーションに引っかかることによる停止なのですが、InnoDBからデータを取得する際に意図しない形でデータが取得されていて停止するようです。
MySQL 8.0 ではフォーラムで報告されていた memcached plugin 周りのいくつかの修正が取り込まれており、コードもそれなりに変更されているのですが、この問題はまだ修正されていないようです。 ネット検索では同じように停止する報告を見つけられなかったので本格的に使おうと思った人がいないのでは?という不安もあり、あまりにも簡単に停止するので検証を断念しました。
チューニングパラメータ
使えないと書いた上で紹介するのも変な話ですが、いくつかのパラメータを調整するとInnoDB memcached pluginを高速に動作させることができます。
https://dev.mysql.com/doc/refman/5.6/ja/innodb-memcached-tuning.html
単にmemcachedの代替として使用する場合、innodb_doublewrite=0
や innodb_flush_log_at_trx_commit=2
のように設定すると高速に動作します。
トランザクションオーバーヘッドの削減 パラメータ daemon_memcached_r_batch_size
と daemon_memcached_w_batch_size
は共に大きな値を設定すると、
ロックが多発しパフォーマンスが大幅に低下してしまうので、エラーログにロックの記載がある場合はどちらも1に設定したほうがいい性能が出ることもあります。
余談
これだけ簡単に停止させられるのであれば、Amazon RDSのMemcacheプラグインも停止するのでは?と思い同じ条件で試してみましたがRDSは停止しませんでした。 うまく調整されているのか謎です。
こころがしんどい
— シリル@ガルパ沼🍊⚓️😈 (@d_cyrill1129) 2016年10月1日
ISUCON6予選問題のPHP実装を担当しました
こんにちはの方もはじめましての方もエントリーを読んでいただきありがとうございます。
昨日から開催されている ISUCON6 の予選にてPHP実装のコーディングを担当させていただきました t-cyrill と申します。 日頃はWeb屋さんでインフラのお仕事をやっています。
今回はいつものような適当なエントリーではなく少ししっかりとしたエントリーで担当しましたPHP実装について、いくつか簡単な補足をさせていただきます。
はじめに
ISUCON6予選参加者のみなさま、お疲れさまでした。 たくさんのチームの方にPHP実装を触っていただけたようでありがとうございます。
ISUCONということで多くの人に触れていただくコードになるだろうと思い、どのチームの方にも得意不得意の影響があまりないようになるべくよく知られたライブラリを使ったり、元からPHPがうまく動作するような環境を用意できるように準備したつもりです。
いくつか至らない点もあったと思いますが、もし困るところがあまりなかったようでしたら幸いです。
実装に使用したライブラリなど
composer.lock
を見ていただればわかることですが、今回はなるべく初期のPerl実装に近くなるようにライブラリを選びました。
軽量フレームワークの Slim3
、HTTPクライアントの Guzzle6
、テンプレートエンジンの Twig
などPHPな方にはよく見るようなライブラリを元にして作っていきました。
Twigを選択したのは元になったPerlテンプレート内でテンプレート継承を使用していたためですが、今思えば特に必要ではなかったような気もします。
独自実装を使ったところなど
Perl実装から移す際にPHPで用意できなかったrandom_string
など一部の関数は元の実装コードとそれほど違和感がないように独自に実装しました。
これらの関数は glue.php
にまとまっています。
本質的なところではないのですが、 random_string
の実装はかなり雑で、Perl実装のように柔軟なランダム文字列を生成することはできません。
pcreの制限について
webapp/Isuda/app.php
の L49 に怪しげな
// NOTE: avoid pcre limitation "regular expression is too large at offset"
というコメントを見かけたPHPの方は嫌な気持ちになったかもしれません。
あまりこのケースに当てはまることがないので意外と知られていないかもしれませんが、PHPのpreg
系関数が内部で使っている正規表現ライブラリpcre
にはデフォルトで渡せる正規表現パターン文字列の長さに制限があります。この制限を変更するには pcre
ビルド時にオプションを指定する必要があります。
今回初期実装の通りに実装すると正規表現文字数が pcre
の制限にかかります。Perl実装から移すときにここはかなり悩みました。
というのも、正規表現を使わない場合PHP実装がやや有利になってしまいますし、pcre
を使うためには独自にpcre
を用意する必要があり、初期ビルド以外のPHPを用意したチームが本質的ではないところでトラブルに遭遇するのは避けたかったのです。
結局、間を取ってハッシュの生成には preg_replace_callback
を分割した正規表現で複数回呼び出して生成し、本来の置換処理はループ後の strtr
にてまとめて行うように実装しました。
余談ですが、Perl実装の動作は正規表現のevalでPHPでは廃止された機能です。
Slim Containerの拡張
細かなところですが各エンドポイントで $this->dbh
や $this->htmlify
のような呼び出しを実現するため、$app
コンテナを継承した独自のSlim Containerを用意しています。
PHP7で入った無名クラスの機能をこのような形で使えたのは少し面白かったです。
stash
Perlではテンプレートへの変数渡しにstash
を使っており、これを模倣するためコンテナのPimple
を直接突っ込んでおきました。
Slimの依存に含まれていたのでいい感じの入れ物として使いましたがこういう使い方は普段しないのであまりよくないような気もしています。
実装ミスについて
途中で気付かれたチームから報告がありましたが、初期のPHP実装にはベンチマーク結果に影響のない2つのわかりやすい実装ミスがあります。
一つは nginx.php.conf
での mime.types
ロード忘れでブラウザで閲覧した際に多くのブラウザでスタイルが適用されないなど見た目の問題が発生します。
+ include mime.types; + default_type application/octet-stream;
もう一つは POST keyword/keyword
を呼び出すと必ず500エラーが発生するというもので、ミドルウェアの指定個所に間違いがあります。
また、同エンドポイントはkeyword
のパース方法も間違っています。
- $keyword = $req->getParsedBody()['keyword']; + $keyword = $req->getAttribute('keyword'); - })->add('authenticate')->add($mw['set_name']); + })->add($mw['authenticate'])->add($mw['set_name']);
しかしながら、ベンチマーカーはPOST keyword/keyword
が成功するのを試さないので、ベンチマークの結果に影響はありませんでした。
ベンチマーカーがPOST keyword/keyword
を試していないことが公開になると他言語実装でも有利になってしまいますし、(特に1日目2日目で情報が違うことになる)
ベンチマークの結果自体には影響のないものでしたので、ルールにのっとり「ベンチマーカーの結果が全てです」という回答としました。 GoやPython実装のバグとは違いこのバグに対してパッチを提供しなかったのはこのような理由です。
2点ともすぐに気づけるようなミスなだけにPHP実装を試していただいた方には申しわけなかったです。
初期実装のサーバについて
初期実装のサーバは予選時には nginx + phpfpm の構成としました。
もともとはビルトインサーバを使用して簡単に呼び出す予定でしたが、並列処理性に問題があるためベンチの初期チェックを通過できなかったため、Ruby実装がunicornを用意したタイミングでphp-fpmを使うようにsystemd unitを置き換えました。
pm
も"static"に設定されたのでPerlほどではありませんがPHPの初期スコアはそれなりに出るようになっていたと思います。
実装の最適化について
いくつかのチームから解説が出るでしょうし、PHP実装もそちらを参考にしていただければ同じように速くなりますが、初期実装でわざと遅くなりそうにした個所のみ補足します。
PHP-FPMのtcp呼び出し
初期実装で php-fpm
は 9000
と 9001
ポートでlistenしており、nginxからプロキシする形で用意されています。
php-fpm にはunix domain socketでlistenする機能がありますので置き換えることでパフォーマンスがわずかに改善します。
最後に
本選でPHP実装を担当することはおそらくありませんが、本選でもPHP実装が上位チームに入ってくれることを期待しています。 それでは本選でお会いしましょう。
C90夏コミありがとうございました&サークル活動の休止について
C90でゆきいろパラソルのブースに来てくださったみなさま、ありがとうございました。
今回も無事「ひだまりPHPシリーズ」の新刊を出すことができました。
あと、10部ほどコピー本も用意してみました。Kinko'sさんで初めて作ってみたのですが、無事刷れてよかったです。超大変でした!中身はもちろん、今回初めて表紙絵描きました!(前日まで間に合うよ!すごいね)
ImageMagickで作った(!)巨大PDFをUSBに入れて持っていくだけで Kinko's お兄さんがいい感じにプリンタ設定してくれました。すごいね。
Kinkosのコピー機めっちゃ面白かった
— シリル@夏コミお疲れ様でした! (@d_cyrill1129) 2016年8月12日
設営終わりました!本めっちゃあります!たすけて!
— シリル@夏コミお疲れ様でした! (@d_cyrill1129) 2016年8月13日
今日はよろしくお願いします!!! pic.twitter.com/FL8dkPwyBt
そんなこんなで三度目となるサークル参加となったC90も楽しい3日間でした。
今後のサークル活動についてですが、ゆきいろパラソルとしての活動は一旦おやすみとします。
ひだまりPHPシリーズが一通り書けたというのと、今後の広がりがあまり想像できなくなったというのが理由です。すみません。
ほかに書くことが見つかるまで、こちらのブログは引き続き更新していきますのでお付き合いいただければ幸いです。