まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

タグ:rhel

日本時間の 2016 年 4 月 1 日に、レッドハット社から驚きの発表がありました:
No-Cost RHEL Developer Subscription now available

2016040101



開発(者)向け、という条件は付きますが、RHEL(RedHat Enterprise Linux) を含む Devloper Suite が無料でダウンロード可能になった、というものです。マジか!?これはタチの悪いエイプリルフールだろ?と思ったのですが、このニュースは米国時間の 3 月 31 日にリリースされており、エイプリルフールではなさそうです。。

自分はこれまで RHEL のコミュニティ版ともいえる CentOS ばかり使っていましたが、ついにこの領域にレッドハット社が脚を踏み入れることになるとは。。 色々な事情や背景も考えられますが、なにはともあれ使えるものなら使ってみたいわけです(笑)。試してみました。


まずは RHEL のダウンロードサイトへ行ってみると、既にこの発表を反映した内容になっています:
http://developers.redhat.com/products/rhel/download/

2016040102


このサイトから RHEL 7 がダウンロードできるようになっている模様です。リンクをクリックすると、アカウントログインが求められます。RedHat Developer アカウントを持っている場合は入力、持っていない場合は新規に作成してログインします。各種SNSの情報に紐付けたサインインもできるようです:
2016040103


そしてアカウントプロファイル作成後にログインすると、その場から RHEL サーバーの ISO イメージのダウンロードが開始されました(バージョン 7.2 の 64bit 版でした。そういや 7.x って 32bit 版ないんだっけ)。インストールなど、ダウンロード後の作業手順についてもここから参照できるようです:
2016040104


といっても特別な手順が必要なわけではなく、普通に ISO(DVD) からブートできます:
2016040105


インストーラーも普通でした。最初に日本語選んでおけばインストール作業から日本語GUIで行えます:
2016040106


インストールが完了してリブートした直後の画面がこちらです。"LICENSE INFORMATION" に警告マークがついているので、ここをクリックします:
2016040107


ライセンス条項を読み、確認して、同意にチェックを入れ、左上の「完了」ボタンで戻ります:
2016040108


画面が戻ると先程の警告マークが消えているはずです。右下のボタンで設定を完了します:
2016040109


「ようこそ」画面が出るので更に進めていきます。すると・・・:
2016040110


じゃーん!
2016040101


個人的には見る機会の少ない RedHat Enterprise Linux のデスクトップ画面が表示されました。7.x になってからは本当に初めてかもしれない。。 ともあれ、無料のアカウント登録だけで本当に使えてしまいました。

動いてしまえば、後は慣れた CentOS の感覚(?)で使えるようになります:
2014040101






(注 この記事の内容は少し古くなってしまっています。2017年1月時点の最新内容はこちらからどうぞ)


メインフレーム(IBM z Systems)版 Linux 環境である LinuxONE が無償利用可能なクラウドコミュニティサービスとして公開されました:
https://developer.ibm.com/linuxone/


アプリケーション開発者や学生さんであれば、ユーザー登録するだけで LinuxONE 版の RHEL(RedHat Enterprise Linux) を最大90日間利用することができます(root 権限もあります)。メインフレーム版の Linux の使い勝手やパフォーマンス、そしてアプリケーション互換性など気になります。試しに自分も使ってみました。

日本語での利用ガイドはこちらにあります(PDF)。この手順で実際にアクセスできる環境の構築まではできますが、その後使ってみるとちょっと気になったので補足したり、実際に使い始めてみての印象も含めて自分なりの感想を書き綴ってみたつもりです:
http://www-03.ibm.com/systems/jp/resources/linuxone_cc-quick-start-guide.pdf


ちなみにこの環境はニューヨーク州ポケプシーにあるマリスト大学内に LinuxONE を設置して、ホスティング環境を提供いただいて実現しています。つまり接続先はニューヨークになります:
Marist College Partners with IBM and Linux Foundation to Support Linux on the Mainframe


では実際にユーザー登録して使ってみましょう。まずは LinuxONE Community Cloud サイトにアクセスして、トップページの "Register NOW" と書かれたボタンをクリックします:
2015121801



名前やメールアドレスなどの利用者情報を入力します。途中に携帯電話番号を指定する箇所があり、確認のためその携帯電話に送られる認証コードを入力して進める、という流れになっています:
2015121802



ここでの手続きが完了するとこのような画面になります。この後登録したメールアドレスに何通かのメールが順次送られてきます:
2015121803


そのうちの一通がこちらです。LinuxONE Community Cloud のダッシュボード画面への URL が記載されているのでメモしておきましょう:
2015121813


別メールでこのような内容が送られてきます。上記のダッシュボードにログインするための情報が記載されています:
2015121812



ここまでの情報が揃っていれば実際に LinuxONE Community Cloud を利用することができるようになります。上記のメールで送られてきた URL にブラウザでアクセスすると、このようなログイン画面が表示されます。別メールで送られてきた User ID とパスワードを指定してログインします:
2015121804


ログイン直後はこのような画面になります。OS イメージとか色々気になりますが、実際に作ったインスタンスにアクセスするには SSH 鍵ペアが必要になるので、最初に作って(登録して)おきます。"Access" と書かれたタブをクリックします:
2015121801


"Access" タブの "Key Pairs" 画面に移ると現在登録されている鍵の一覧が表示されます(この時点では何も登録されていないはずです)。新規に作成してもいいですし、手持ちの鍵ペアをインポートする形で登録しても、どちらでも構いません。私は自分が持っていた SSH 鍵をインポートして使うことにしたので後者の手順を紹介します(自分で鍵を作成する手順はこちらを参照ください)。画面内一番右の "Import" アイコンをクリックします:
2015121802


環境(LinuxONE Community Cloud)と鍵の名前(任意)、そしてインポートしたい公開鍵の内容をペーストするか、あるいは "Browse" で公開鍵ファイルを指定して、"Import" します:
2015121803


新規作成やインポートが成功するとこんな感じの画面になります。正しく認証鍵が登録できました:
2015121804


ではこの鍵を使って Linux インスタンスを作成してみます。"Images" タブを開いて利用可能なイメージの一覧を確認します。現時点では素の RHEL6.7 環境と、RHEL6.7 に MongoDB が付属している(と思われる)環境の2つのイメージが登録されて使えるようになっていました。どちらでもいいのですが、とりあえずは最小構成を試してみたいので前者を選択します:
2015121805


RHEL6.7 イメージの内容が表示されます。これをインスタンスとしてデプロイしたいので "Deploy" ボタンをクリックします:
2015121807


デプロイ時の情報入力画面に切り替わります。ここに必要な情報を入力/指定していきます:
2015121808


Name には任意の名称を入力します。注意点として Project はデフォルトの "Public" ではなく、自分に割り当てられたプロジェクト ID (要するに "Public" じゃない方)を指定し直してください。なおインスタンスの有効期限も指定できますが、デフォルトで最長の90日間になっているはずです:
2015121806


続きです。System の Flavor (規模)は "m1.linuxone" が唯一の選択肢になっているはずなので、これを選びます。この Flavor で CPU x 2、メモリ 2GB のスペックになります。そして Access and Security では上記で作成した鍵ペアの名前を必ず指定してください(これをしないと作成したインスタンスにアクセスする術がなくなります)。最後に "Deploy" ボタンをクリックすると作成が開始されます:
2015121807


画面が切り替わり、インスタンスが作成中である旨のメッセージが表示されます:
2015121810


画面をリロードすると、インスタンスが作成中であることがわかります:
2015121811


しばらく待つと作成したインスタンスの Status が OK となります。これでインスタンスが作成され、起動も完了したことになります。名前部分をクリックしてインスタンスの詳細を確認しましょう:
2015121812


インスタンスの詳細画面です。この中にパブリック IP アドレスが記載されているので、この値をメモしておきましょう:
2015121808


では作成した LinuxONE のサーバーインスタンスにアクセスして実際に使ってみましょう。Teraterm などの SSH クライアントを使って、先程メモした IP アドレスに SSH アクセスします。その際のユーザー名には "linux1"、秘密鍵にはあらかじめ作成した(あるいは作成してダウンロードした)秘密鍵ファイル、そしてパスフレーズには秘密鍵作成時に指定したパスフレーズを入力してアクセスします:
2015121809


プロンプトが表示されればログイン成功です!:
2015121810


とりあえず cpuinfo とシステム名を確認してみました。間違いなく IBM/S390 システムで CPU は2個確認できます:
2015121811


この linux1 ユーザーは sudo 権限を持っているので root 権限でコマンドを実行したり、rpm や yum コマンドで新たにアプリケーションをインストールしたりすることもできます。軽く使ってみた感じでは「Intel 版の RHEL(CentOS) とほとんど変わらない、というか違いを感じない」という印象です。

1つだけ、環境を見ていて気付いたのはイーサネットの設定で DNS サーバーが指定されていないことでした(つまり名前解決ができません)。私は /etc/sysconfig/network-scripts/ifcfg-eth0 に以下の1行を追加(Google の公開 DNS サーバーを指定)して再起動することで解決しています:
  :
  :
DNS1=8.8.8.8


RHEL 環境としては Intel 版とほぼ変わらないことを確認するため、試しにこの記事を参考にして、LinuxONE に X Window と VNC サーバーをインストールして、VNC クライアントからデスクトップ環境にアクセスしてみました(実際、リンク先の記事と同じ手順に加えて、デフォルトで有効になっていた iptables を外すだけで実現できました):
2015121800



その他、ざっと yum でのインストールを試してみた感じではこんな結果でした:
アプリケーションインストール可否コメント
X Windowyum groupinstall "X Window"
Tiger VNCyum install tigervnc-server
OpenJDK不可yum リポジトリに見つからない
(ただし標準で 1.5.0 導入済み)
IBM JDKyum install java-1.7.1-ibm-devel
PHPyum install php php-mbstring php-mysql ..
Tomcat(6)yum install tomcat6 tomcat6-webapps tomcat6-admin-webapps
Apache HTTPDyum install httpd
MySQLyum install mysql-server
FireFoxyum install firefox
Eclipse不可yum リポジトリに見つからない
OpenOffice/LibreOffice不可yum リポジトリに見つからない
screenyum install screen
tmuxソースからコンパイルしてビルド 参照
x3270 エミュレータyum install x3270 x3270-text x3270-x11


標準の yum リポジトリでは見つからない、というだけの可能性もあるので、不可になっているものが実際には可能だったりすることもあると思います。個人的には新し目の JDK を見つけておけると色々使えそう、という印象です。LAMP デベロッパーに関してはほぼ困らないのかも。。

(2016/Jan/15 追記)
標準リポジトリから IBM Java の 1.7.1 がインストールできることを確認しました:
# yum install java-1.7.1-ibm-devel


IDCフロンティア様主催の MariaDB ミートアップに参加してきました。

MariaDB は MySQL 互換の RDB です。自分自身が作って運営しているマンホールマップねっぴツイートマッパーなど多くのサービスで MariaDB を採用しています。

このミートアップの中で現 Chief Evangelist の Colin さんから「MariaDB は IBM の Power8 プラットフォーム上で非常に高いパフォーマンスを発揮している」という紹介がありました。おそらくこの記事で紹介されていることだと思います:

MariaDB on Power8

ほー、そうなのか(知らなかったw)。ただ、実は以前に自分もこのようなブログエントリを書いたことがありました:
Power Linux 上で MariaDB をビルドして使う

これを書いた頃はまだ(後述の)PDP 環境で提供される RedHat のバージョンが 6 でした。RHEL 6 では標準 RDB が MySQL でしたが、RHEL 7 になって標準 RDB は MariaDB に変更になっているはずです。つまり「もうわざわざビルドしなくても Power Linux 上で MariaDB が使えるようになっているはず」です。

さっそく試してみます。環境としては IBM がビジネスパートナー様向けに無料で提供しているクラウドの Power 環境である PDP を使って Power8 + RedHat 7 環境を予約して使います。この辺りの詳しい手順はこちらを参照ください:
Power 版 RHEL(RedHat Enterprise Linux) を無料で2週間借りる(1/2)
Power 版 RHEL(RedHat Enterprise Linux) を無料で2週間借りる(2/2)


上記の (1/2) の手順でマシンリソースの予約を行い、(2/2) の手順で SSH でリモートアクセスして Power8 のリモート環境にログインします:
2015060907


念のため環境を確認します。まごうことなき Power 8 アーキテクチャ上の RedHat Enterprise Linux 7.1 です。:
2015060909


ではさっそくというか、いきなり MariaDB のインストールにとりかかります。リポジトリなどの準備なしでいきなり yum install を実行すると・・・
[root@sys-74413 ~]# yum install mariadb-server mariadb-client mariadb-devel
Loaded plugins: product-id, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
No package mariadb-client available.
Resolving Dependencies
--> Running transaction check
---> Package mariadb-devel.ppc64le 1:5.5.41-2.ael7b will be installed
--> Processing Dependency: openssl-devel(ppc-64) for package: 1:mariadb-devel-5.5.41-2.ael7b.ppc64le
---> Package mariadb-server.ppc64le 1:5.5.41-2.ael7b will be installed
--> Processing Dependency: mariadb(ppc-64) = 1:5.5.41-2.ael7b for package: 1:mariadb-server-5.5.41-2.ael7b.ppc64le
--> Processing Dependency: perl-DBI for package: 1:mariadb-server-5.5.41-2.ael7b.ppc64le
--> Processing Dependency: perl-DBD-MySQL for package: 1:mariadb-server-5.5.41-2.ael7b.ppc64le
--> Processing Dependency: perl(DBI) for package: 1:mariadb-server-5.5.41-2.ael7b.ppc64le
--> Processing Dependency: libaio.so.1(LIBAIO_0.4)(64bit) for package: 1:mariadb-server-5.5.41-2.ael7b.ppc64le
--> Processing Dependency: libaio.so.1(LIBAIO_0.1)(64bit) for package: 1:mariadb-server-5.5.41-2.ael7b.ppc64le
--> Processing Dependency: libaio.so.1()(64bit) for package: 1:mariadb-server-5.5.41-2.ael7b.ppc64le
--> Running transaction check
---> Package libaio.ppc64le 0:0.3.109-12.ael7b will be installed
---> Package mariadb.ppc64le 1:5.5.41-2.ael7b will be installed
---> Package openssl-devel.ppc64le 1:1.0.1e-42.ael7b will be installed
--> Processing Dependency: zlib-devel(ppc-64) for package: 1:openssl-devel-1.0.1e-42.ael7b.ppc64le
--> Processing Dependency: krb5-devel(ppc-64) for package: 1:openssl-devel-1.0.1e-42.ael7b.ppc64le
---> Package perl-DBD-MySQL.ppc64le 0:4.023-5.ael7b will be installed
---> Package perl-DBI.ppc64le 0:1.627-4.ael7b will be installed
--> Processing Dependency: perl(RPC::PlServer) >= 0.2001 for package: perl-DBI-1.627-4.ael7b.ppc64le
--> Processing Dependency: perl(RPC::PlClient) >= 0.2000 for package: perl-DBI-1.627-4.ael7b.ppc64le
--> Running transaction check
---> Package krb5-devel.ppc64le 0:1.12.2-14.ael7b will be installed
--> Processing Dependency: libverto-devel for package: krb5-devel-1.12.2-14.ael7b.ppc64le
--> Processing Dependency: libselinux-devel for package: krb5-devel-1.12.2-14.ael7b.ppc64le
--> Processing Dependency: libcom_err-devel for package: krb5-devel-1.12.2-14.ael7b.ppc64le
--> Processing Dependency: keyutils-libs-devel for package: krb5-devel-1.12.2-14.ael7b.ppc64le
---> Package perl-PlRPC.noarch 0:0.2020-14.ael7b will be installed
--> Processing Dependency: perl(Net::Daemon) >= 0.13 for package: perl-PlRPC-0.2020-14.ael7b.noarch
--> Processing Dependency: perl(Net::Daemon::Test) for package: perl-PlRPC-0.2020-14.ael7b.noarch
--> Processing Dependency: perl(Net::Daemon::Log) for package: perl-PlRPC-0.2020-14.ael7b.noarch
--> Processing Dependency: perl(Compress::Zlib) for package: perl-PlRPC-0.2020-14.ael7b.noarch
---> Package zlib-devel.ppc64le 0:1.2.7-14.ael7b will be installed
--> Running transaction check
---> Package keyutils-libs-devel.ppc64le 0:1.5.8-3.ael7b will be installed
---> Package libcom_err-devel.ppc64le 0:1.42.9-7.ael7b will be installed
---> Package libselinux-devel.ppc64le 0:2.2.2-6.ael7b will be installed
--> Processing Dependency: libsepol-devel >= 2.1.9-1 for package: libselinux-devel-2.2.2-6.ael7b.ppc64le
--> Processing Dependency: pkgconfig(libsepol) for package: libselinux-devel-2.2.2-6.ael7b.ppc64le
--> Processing Dependency: pkgconfig(libpcre) for package: libselinux-devel-2.2.2-6.ael7b.ppc64le
---> Package libverto-devel.ppc64le 0:0.2.5-4.ael7b will be installed
---> Package perl-IO-Compress.noarch 0:2.061-2.ael7b will be installed
--> Processing Dependency: perl(Compress::Raw::Zlib) >= 2.061 for package: perl-IO-Compress-2.061-2.ael7b.noarch
--> Processing Dependency: perl(Compress::Raw::Bzip2) >= 2.061 for package: perl-IO-Compress-2.061-2.ael7b.noarch
---> Package perl-Net-Daemon.noarch 0:0.48-5.ael7b will be installed
--> Running transaction check
---> Package libsepol-devel.ppc64le 0:2.1.9-3.ael7b will be installed
---> Package pcre-devel.ppc64le 0:8.32-14.ael7b will be installed
---> Package perl-Compress-Raw-Bzip2.ppc64le 0:2.061-3.ael7b will be installed
---> Package perl-Compress-Raw-Zlib.ppc64le 1:2.061-4.ael7b will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package                     Arch        Version               Repository  Size
================================================================================
Installing:
 mariadb-devel               ppc64le     1:5.5.41-2.ael7b      server     747 k
 mariadb-server              ppc64le     1:5.5.41-2.ael7b      server      11 M
Installing for dependencies:
 keyutils-libs-devel         ppc64le     1.5.8-3.ael7b         server      37 k
 krb5-devel                  ppc64le     1.12.2-14.ael7b       server     640 k
 libaio                      ppc64le     0.3.109-12.ael7b      server      24 k
 libcom_err-devel            ppc64le     1.42.9-7.ael7b        server      30 k
 libselinux-devel            ppc64le     2.2.2-6.ael7b         server     174 k
 libsepol-devel              ppc64le     2.1.9-3.ael7b         server      71 k
 libverto-devel              ppc64le     0.2.5-4.ael7b         server      12 k
 mariadb                     ppc64le     1:5.5.41-2.ael7b      server     9.1 M
 openssl-devel               ppc64le     1:1.0.1e-42.ael7b     server     1.2 M
 pcre-devel                  ppc64le     8.32-14.ael7b         server     477 k
 perl-Compress-Raw-Bzip2     ppc64le     2.061-3.ael7b         server      33 k
 perl-Compress-Raw-Zlib      ppc64le     1:2.061-4.ael7b       server      58 k
 perl-DBD-MySQL              ppc64le     4.023-5.ael7b         server     140 k
 perl-DBI                    ppc64le     1.627-4.ael7b         server     802 k
 perl-IO-Compress            noarch      2.061-2.ael7b         server     260 k
 perl-Net-Daemon             noarch      0.48-5.ael7b          server      51 k
 perl-PlRPC                  noarch      0.2020-14.ael7b       server      36 k
 zlib-devel                  ppc64le     1.2.7-14.ael7b        server      50 k

Transaction Summary
================================================================================
Install  2 Packages (+18 Dependent packages)

Total download size: 24 M
Installed size: 124 M
Is this ok [y/d/N]: 

Power 用の RHEL7 でも、ちゃんと MariaDB が標準で使えるようになってました。これで "y" を指定すればインストールできちゃいます。

ただし、このコマンドで導入できるのは MariaDB 5.5 のようですね。MariaDB 10.x を使いたい場合はまだソースからビルドする必要がありそうです。その手順はこちらのエントリを参照してください:
Power Linux 上で MariaDB をビルドして使う

 

CentOS / RHEL(RedHat Enterprise Linux) に Ruby 2.x をインストールする手順を紹介します。

Ruby のバージョンにこだわらないのであれば、コマンドラインから
# yum install ruby
と入力するだけでインストールできます。ただ 2015/Feb/18 現在、この方法でインストールできる Ruby のバージョンは 1.8.7 でした。このバージョンで特に支障がなければこの方法が一番簡単だと思っています。


以下、どうしても Ruby 2.x を使いたい、という人のための導入方法の紹介です。CentOS で Ruby 2.x を導入する方法はいくつかあって、ソースコードからビルドするという一般的な手順もあるのですが、ここでは rbenv を使った方法を紹介します。

rbenv は複数バージョンの Ruby を同一コンピュータ上で管理する GitHub 提供のツールです。2.x に限らず 1.x も含めた複数バージョンの Ruby を同じマシンにインストールし、実際に利用するバージョンを管理しながら使えるようにできます。このツールを使って Ruby の最新版をインストールしてみます。


まず、rbenv は GitHub から提供されていることもあり、git の入手が必須です。まだ導入できていない場合はこのコマンドで git を導入してください:
# yum install git

そして git を使って GitHub から rbenv をチェックアウトします。今回は /opt/ 以下に Ruby をインストールするという前提にします:
# cd /opt
# git clone git://github.com/sstephenson/rbenv.git

続けて ruby-build プラグインを rbenv の plugins フォルダにインストールします:
# mkdir /opt/rbenv/plugins
# cd /opt/rbenv/plugins
# git clone git://github.com/sstephenson/ruby-build.git

最後に /etc/profile に以下の3行を追加して、rbenv を初期化&実行するための環境設定を行います:
export RBENV_ROOT="/opt/rbenv"
export PATH="${RBENV_ROOT}/bin:${PATH}"
eval "$(rbenv init -)"

ここまでの作業で rbenv の導入が完了しました。再ログインするとか、シェルを再起動するなりして最後の環境設定までが反映された状態にしてください。

更に、この後の作業で必要になるモジュールを(エラーが出る前に)yum でインストールしておきます:
# yum install gcc make openssl-devel libffi-devel

ここまでの準備ができていれば Ruby のインストール作業に移れます。まずは rbenv でインストールできる Ruby のバージョン一覧を確認してみます:
# rbenv install -l
Available versions:
  1.8.6-p383
  1.8.6-p420
  1.8.7-p249
  1.8.7-p302
  1.8.7-p334
  1.8.7-p352
  1.8.7-p357
  1.8.7-p358
    :
    :
  2.1.5
  2.2.0-dev
  2.2.0-preview1
  2.2.0-preview2
  2.2.0-rc1
  2.2.0
  2.3.0-dev
  jruby-1.5.6
    :
    :
  ree-1.8.7-2012.02
  topaz-dev

JRuby とかもリストされてますが、今回は普通(?)の Ruby だけで考えます。バージョン番号に rc とか dev とか preview とか付いているのは開発中のものだったりします。この一覧を見る限り安定版では 2.2.0 が最新のようなので、これをインストールしてみましょう(結構時間かかります):
# rbenv install 2.2.0
Downloading ruby-2.2.0.tar.gz...
    :
    :


そして、この Ruby 2.2.0 をシステムで使うデフォルトバージョンとして設定した上で動作確認します:
# rbenv global 2.2.0
# ruby -v
ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-linux]

Ruby 2.2.0 が導入できました! 


この後で別のバージョンが必要になった場合は同様に
# rbenv install X.X.X

でインストールし、
# rbenv global X.X.X

でデフォルトバージョンを変更できます。







 

KVM(Kernel-based Virtual Machine) は CentOS/RHEL(RedHat Enterprise Linux) 環境に標準装備の仮想ハイパーバイザーです。わかりやすく言えば、VMWare Server のような機能がカーネルにはじめから用意されている(はじめから有効にはなっていない)ので、CentOS/RHEL でも、それ以外の Linux ディストリビューションでも単体で仮想環境を構築することができます。 僕も自宅の個人環境で使っています。KVM 環境の構築手順はこちらのエントリを参照ください:
CentOS に KVM 環境を構築する


KVM には GUI/CUI 両方の管理ツール/コマンドが用意されていて、仮想イメージのクローン(複製)なども行うことができます。ただこの複製ツールが手軽に使えるかというと、実用上ちょっとした問題がありました。
2015021801


その問題点は、この「複製」というのは「仮想イメージをまるごと複製」するのですが、ホスト名と MAC アドレスまでまるごと複製してしまう、という点でした。つまりあるサーバーインスタンスのイメージを複製すると、同じホスト名で、同じ MAC アドレスのネットワークインターフェースを持った異なるサーバーが用意される、ということです。 またネットワーク設定も複製されるため、例えば固定 IP アドレスが設定されている環境であれば同じ IP アドレスが割り振られることになりますし、DHCP 設定だとすると、同じ MAC アドレスのサーバーが別に存在していることになり、DHCP サーバーからは区別ができません(結果、正しい IP アドレスが取得できず、ネットワークが使えない状態で起動してしまいます)。


要は、複製コマンドそのものに問題があるわけではない(むしろ、複製という意味では正しい)のですが、イメージを複製した後にホスト名と MAC アドレスを変更したい(そこまで含めて自動化したい)のです。ただホスト名は AAA から BBB に変更すればよい、という正解が決まっているのでいいとして、MAC アドレスは変更したいといっても「では変更後の値を何にするのか?、一意に生成できるのか?」という問題もあったりして単純ではありません。またこれらの処理を自動化するとなると、起動していない仮想サーバーイメージ内のファイルシステムを外から操作することになるので、これも特殊なコマンドを使うことになります。その辺りを含めてシェルスクリプト化するまでを紹介します。


というわけで、目標として今回は clone-guest.sh というシェルスクリプトを作って、
# clone-guest.sh AAA BBB
というコマンドで、AAA という仮想マシンイメージを BBB という仮想マシンに複製できるようにします。複製そのものは /usr/bin/virt-clone コマンドを使えばできるのですが、その際に BBB は AAA とは異なる MAC アドレスを持っているように変更します。また複製後にこの BBB を自動起動するようにしてみます。また今回作成するシェルスクリプトでは複製の対象を CentOS/RHEL とします(これらのシステムを前提として MAC アドレス変更の処理を追加するためです)。


まず最初に「そもそもホスト名と MAC アドレスの変更ってどうやるの?」という疑問が生じます。ホスト名については CentOS/RHEL では /etc/sysconfig/network 内に HOSTNAME=**** として記載されているので、ここを書き換えるだけで済みます。具体的には例えば複製元の /etc/sysconfig/network に HOSTNAME=AAA.domain.com のような記載が含まれていたら、複製先では HOSTNAME=BBB.domain.com と書き換えればいい、ということになります。

一方、MAC アドレスはちと複雑です。まず MAC アドレスを書き換える必要のあるファイルが、
 - /etc/sysconfig/network-scripts/ifcfg-eth0
 - /etc/udev/rules.d/70-persistent-net.rules
の2つあります。更に書き換え後の MAC アドレスは現在とは異なる一意の値にする必要があるため、どのように生成するか、という問題も含まれているのでした。ここは詳しくは後述しますが /usr/bin/uuidgen コマンドを使って動的に取得するようにします。
 

次に、起動していない仮想イメージファイル内のファイルシステムへどのようにアクセスするか? ですが、こちらは KVM 標準の以下のコマンドを活用して実現します:
- /usr/bin/virt-cat     外部から仮想イメージ内の特定ファイルに対して cat を実行する
- /usr/bin/virt-copy-in 外部から仮想イメージ内の特定ファイルにコピーする

これらのツールと、KVM の一般的な仮想管理コマンドである virsh(/usr/bin/virsh) を組み合わせて、clone-guest.sh を以下のような内容で作りました。青字は僕のコメントです:
#!/bin/sh

# 作業ディレクトリ
work_dir=/tmp/clone-guest

# この作業で使う各種コマンド
cmd_awk=/bin/awk
cmd_cat=/bin/cat
cmd_cut=/bin/cut
cmd_grep=/bin/grep
cmd_mkdir=/bin/mkdir
cmd_sed=/bin/sed
cmd_uuidgen=/usr/bin/uuidgen
cmd_arp=/sbin/arp
cmd_virsh=/usr/bin/virsh
cmd_virt_cat=/usr/bin/virt-cat
cmd_virt_clone=/usr/bin/virt-clone
cmd_virt_copy_in=/usr/bin/virt-copy-in

source_bridge=br0 # KVM のブリッジインターフェース名(デフォルトだと virbr0)
original_domain_name=$1 # 複製元(AAA)
clone_domain_name=$2 # 複製先(BBB)

# 仮想イメージのあるディレクトリ
domain_image_dir=/var/lib/libvirt/images
clone_domain_image_path=$domain_image_dir/$clone_domain_name.img # 複製先仮想イメージファイル


# パラメータを2つ(複製元と複製先)指定して実行していることを確認
if [ "$clone_domain_name" = "" ] ; then
echo "Usage: clone-guest.sh <domain_name> <clone_name>"
exit 0
fi

# 作業ディレクトリが存在していなかったら作成
[ ! -e $work_dir ] && $cmd_mkdir -p $work_dir


# virt-clone コマンドで普通に複製
$cmd_virt_clone \
  --original $original_domain_name \
  --name $clone_domain_name \
  --file $clone_domain_image_path 

# 複製前の仮想イメージ内の /etc/sysconfig/network を取り出して作業ディレクトリに保存
$cmd_virt_cat -d $original_domain_name \
  /etc/sysconfig/network \
  > $work_dir/network.org

# 複製前の仮想イメージ内の /etc/sysconfig/network-scripts/ifcfg-eth0 を取り出して作業ディレクトリに保存
$cmd_virt_cat -d $original_domain_name \
  /etc/sysconfig/network-scripts/ifcfg-eth0 \
  > $work_dir/ifcfg-eth0.org

# 複製前後の仮想イメージの MAC アドレスを取り出す
original_mac_addr=$( \
$cmd_virsh domiflist $original_domain_name \
| $cmd_grep $source_bridge \
| $cmd_awk '{print $5}' \
)
clone_mac_addr=$( \
$cmd_virsh domiflist $clone_domain_name \
| $cmd_grep $source_bridge \
| $cmd_awk '{print $5}' \
)

# 複製前後の仮想イメージの UUID を取り出す
original_nic_uuid=$( \
$cmd_cat $work_dir/ifcfg-eth0.org \
| $cmd_grep -i uuid \
| $cmd_cut -d'=' -f2 \
| $cmd_sed 's/"//g' \
)
clone_nic_uuid=$($cmd_uuidgen)

# 複製後の仮想イメージの ifcfg-eth0 を書き換え
$cmd_cat $work_dir/ifcfg-eth0.org \
| $cmd_sed -e "s/$original_mac_addr/$clone_mac_addr/i" \
-e "s/$original_nic_uuid/$clone_nic_uuid/i" \
> $work_dir/ifcfg-eth0

# 複製後の仮想イメージに書き換え後の ifcfg-eth0 を書き戻す
$cmd_virt_copy_in -d $clone_domain_name \
  $work_dir/ifcfg-eth0 \
  /etc/sysconfig/network-scripts/

# 複製前の仮想イメージ内の /etc/udev/rules.d/70-persistent-net.rules を取り出して作業ディレクトリに保存
$cmd_virt_cat -d $original_domain_name \
  /etc/udev/rules.d/70-persistent-net.rules \
  > $work_dir/70-persistent-net.rules.org

# 複製後の仮想イメージの 70-persistent-net.rules を書き換え
$cmd_cat $work_dir/70-persistent-net.rules.org \
  | $cmd_sed "s/$original_mac_addr/$clone_mac_addr/i" \
  > $work_dir/70-persistent-net.rules

# 複製後の仮想イメージに書き換え後の 70-persistent-net.rules を書き戻す
$cmd_virt_copy_in -d $clone_domain_name \
  $work_dir/70-persistent-net.rules \
  /etc/udev/rules.d/

# 複製後の仮想イメージの network を書き換え
$cmd_cat $work_dir/network.org \
| $cmd_sed -e "s/$original_domain_name/$clone_domain_name/i" \
> $work_dir/network

# 複製後の仮想イメージに書き換え後の network を書き戻す
$cmd_virt_copy_in -d $clone_domain_name \
  $work_dir/network \
  /etc/sysconfig/

# 複製後の仮想イメージを起動
$cmd_virsh start $clone_domain_name

echo "Clone $clone_domain_name has been started."
exit 0

sed だの awk だのを駆使してなんとか作った、という感じです(苦笑)。あとはこのファイルを clone-guest.sh という名前で保存し、実行権限を与え、パスの通ったディレクトリに置いておけば、
# clone-guest.sh AAA BBB

という感じで、既存の AAA という仮想環境を BBB という名前で複製して、各種設定ファイルまで書き換えて、起動する、という使い方ができるはずです。 ここまでできるようになると、KVM もかなり便利に使えてます。










 

このページのトップヘ