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

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

某所で書いていた文書をブログに移行します。
この文書はどちらかというと、自分のメモ用に作って、CentOS の導入時に頻繁に参照していたものです。

0. CentOS とは

CentOS とは商用OSである RHEL(RedHat Enterprise Linux) との完全互換を目指しているフリーの Linux ディストリビューションです。RHEL に含まれているソフトウェアのうち、商用ライセンス/商用パッケージを含まない形でリビルドされた、いわゆる「RHELクローン」の1つです。

CentOS はホームページから誰でも無料でダウンロードして利用することができます。以下、その導入手順を紹介します。

1. 導入メディアの用意

CentOS のページから最新バージョンの最新バージョンの導入メディアの ISO ファイルをダウンロードします。 これから導入するパソコンの CPU が 32bit であれば i386、64bit であれば x86_64と書かれた方を対象にします。

以下では CentOS 6.2 の 64bit 版を前提として記載します。

パソコン実機に導入する場合は ISO ファイルを DVD メディアに焼いておく必要があります。 仮想環境など ISO ファイルのままマウントしてアタッチできるような場合は ISO ファイルのままでも構いません。 またパソコンの BIOS 設定を変更して、DVD からのブート優先度を HDD 以上に上げておいてください。


2. CentOS のインストール

1. で用意した導入メディアを DVD にセットした状態でパソコンを起動します。 DVD が読み込まれて、起動オプションの選択画面が表示されますが、 一番上の Install or upgrade an existing system が選択された状態で Enter キーを押します
centos_install01


CentOS をインストールするための DVD が進行します。
centos_install02


まず、これから導入する DVD のメディア検査を行うかどうかを質問されます。 念のため行なってもいいのですが、この検査はかなり時間がかかります。 すでに導入実績がある場合などであれば Skip を選択しても構いません。
centos_install03


メディアの検査が終わって(あるいはスキップして)先に進めるとインストール開始画面が表示されます。 ここでは Next をクリックして先に進みます。
centos_install04


最初にインストールする環境の言語を選択します。ここでは Japanese(日本語) を選択します。
centos_install05


次はキーボードレイアウトの選択です。日本語キーボードを使っている場合は 日本語 を選択します。
centos_install06


インストール先のストレージデバイスの種類を選択します。 一般的なハードディスクにインストールする場合は Basic Storage Devices を選択します。
centos_install07


選択したストレージデバイスの中に現在含まれているデータの扱いについて確認されます。 まっさらの状態で新規に導入するケースであれば中身を消してしまっても構わないので はい。含まれていません。どのようなデータだっても破棄してください。 を選択します。
centos_install08


次にこれから導入する環境のホスト名を入力します。 ここでは仮に testos.testdomain.com と入力していますが、特定のネットワーク内に接続する場合はその環境に 合わせるなどして名前を指定します。
centos_install09


同じ画面内の左下に Configure Network と書かれたボタンがあります。 ここでネットワーク環境についての設定を行うので、クリックしてください。
centos_install10


ネットワーク接続 というダイアログが表示され、有線や無線のネットワーク設定を行います。 ここでは 有線 タブを選択して、有線ネットワークを設定してみます。 System eth0 と書かれた箇所が選択されていることを確認して、編集 ボタンをクリックします。
centos_install11


System eth0 のネットワーク設定画面です。 まず 自動接続する にチェックを入れて、起動と同時に有線ネットワークが有効になるようにしておきます。
centos_install12


続いて IPv4 のセッティング タブを選択して、IPv4 の設定を行います。 方式 と書かれた箇所を環境に合わせて指定します。 DHCP 環境であれば 自動(DHCP) を選択するだけです。
centos_install13


特定の固定アドレスを手動で設定する場合は、方式を 手動 にした上で 追加 ボタンをクリックし、 アドレス、ネットマスク、ゲートウェイ、DNSサーバー、ドメインなどを指定します。
centos_install14


IPv6 のセッティング タブで IPv6 の設定を行うこともできます。 ここでは 無視する を選択して、IPv6 を利用しない設定にしています。必要であれば設定してください。

最後に 適用 ボタンをクリックします。
centos_install15


ネットワーク接続 画面に戻ります。 閉じる ボタンをクリックして、この画面を終了します。
centos_install16


元の画面に戻りました。次へ ボタンをクリックして続きを行います。
centos_install17


タイムゾーンの設定画面です。アジア/東京 が選択されていることを確認します。
centos_install18


また、この画面の左下の システムクロックで UTC を使用 にチェックを入れます。 これでシステムとしては UTC(世界標準時)が使われた上で、画面上では東京のタイムゾーンで表示されるようになります。
centos_install19


管理ユーザーである root のパスワードを指定します。確認のため、同じ内容を2度入力します。
centos_install20


インストール先のパーティショニングの指定をします。 今回は新規にまっさらの状態で導入するので Use All Space を選択して、 ハードディスク全体を使って導入します。
centos_install21


この画面の左下の パーティションのレイアウトをレビューまたは修正する にチェックを入れて、 次の画面でパーティショニングの内容を確認します。
centos_install22


パーティショニングテーブルが表示されている様子です。 この状態では約 10GB のディスクの 2GB をスワップ領域に、残りを1つのパーティションで ext4 フォーマットで / にマウントしています。 必要であればここでパーティショニングを変更してください。 よく分からなければ、このような1パーティショニング構成でもいいと思います。
centos_install23


ディスクのパーティショニング構成やファイルフォーマットに変更が加わる場合、このような警告画面が表示されます。 全くの新規インストールであれば問題ありませんので、フォーマット を選択して先に進みます。
centos_install24


「ディスクに変更を書き加える」という警告メッセージが表示された場合は Write changes to disk を 選択して、ディスクへの書き込みを許可します。
centos_install25


ディスクのパーティショニングとフォーマットが実行されます。ここでしばらく待ちます。
centos_install26


フォーマットが完了すると、ブートローダーのインストール先を指定する画面が表示されます。 通常はデフォルトのまま /dev/vda にインストールする、というチェックを確認して先へ進みます。
centos_install27


CentOS のインストール内容を選択します。 いくつかの選択肢がありますが、今回は 最小限のインストールを基本に、必要なものだけを加える という例を紹介します。 ここでは最小限のインストールを指定する Minimal を選択します。
centos_install28


画面左下の 今すぐカスタマイズ にチェックを入れます。 これでこの後の画面で Minimal インストールをベースに、必要なものだけを追加していくことになります。
centos_install29


カスタマイズの画面になりました。2画面構成になっていて、左側おおまかなカテゴリーが表示され、 右側にそのカテゴリーに含まれる個別アプリケーションが表示され、インストール内容に含めるかどうかをチェックで指定します。

今回のケースでは開発環境を構築する上で最小限必要と思われるアプリケーションだけを導入する目的で選択します (余計なものを導入すると、トラブル時の原因操作がややこしくなく、という事情もあります)。 この内容に従う必要はありませんが、ここで選択しなくても、後から追加で導入も可能です。 とりあえずはこの内容の通りで行なってみてください。

最初は Hight Availability カテゴリーです。今回のインストールでは何も指定せずに進めます。
centos_install30


続いて Load Balancer カテゴリーです。ここも今回のインストールでは何も指定せずに進めます。
centos_install31


次は Resilient Storage カテゴリーです。ここも今回のインストールでは何も指定せずに進めます。
centos_install32


次は Scalable FileSystem カテゴリーです。ここも今回のインストールでは何も指定せずに進めます。
centos_install33


次は Web サービス カテゴリーです。ここも今回のインストールでは何も指定せずに進めます。
centos_install34


次は アプリケーション カテゴリーです。ここも今回のインストールでは何も指定せずに進めます。
centos_install35


次は サーバー カテゴリーです。ここも今回のインストールでは何も指定せずに進めます。
centos_install36


次は システム管理 カテゴリーです。ここも今回のインストールでは何も指定せずに進めます。
centos_install37


次は デスクトップ カテゴリーです。 ここでは X Window System、デスクトップ、 デスクトップのデバッグとパフォーマンスシステムにチェックを入れて先に進めます。
centos_install38


次は データベース カテゴリーです。ここも今回のインストールでは何も指定せずに進めます。
centos_install39


次は ベースシステム カテゴリーです。 ここでは ベースにチェックを入れて先に進めます。
centos_install40


次は 仮想化 カテゴリーです。ここも今回のインストールでは何も指定せずに進めます。
centos_install41


次は 言語 カテゴリーです。 ここでは 日本語のサポートにチェックを入れて先に進めます。
centos_install42


最後は 開発 カテゴリーです。 ここでは 開発ツールにチェックを入れて先に進めます。
centos_install43


全てのオプション設定が完了したら、画面右下の ボタンをクリックして、 実際のインストールを開始します。
centos_install44


インストールが実行されるとこのようなインジケーターが表示され、必要なアプリケーションとその前提ライブラリの確認が行われます。
centos_install45


実際のインストールが始まるとこのような画面になります。 全てのアプリケーション(この例では 762 個)のインストールが完了するまでしばらく時間がかかりますので、ひたすら待ちます。
centos_install46


全てのアプリケーションのインストールが終わったように見えますが、この後何らかの処理が動いているようで、 この状態のまま、更にもうしばらく待つことになります。
centos_install47


最後の最後にブートローダーがインストールされます。
centos_install48


この画面が表示されれば、無事に DVD(ISO) からの CentOS インストールが完了したことになります。 引き続きセットアップを行うので、再起動 ボタンをクリックして、システムを再起動します。
centos_install49


システムを再起動している時の様子です。 ハードディスクからは最初の起動となることもあって、少し長めに時間がかかります。
centos_install50


再起動されると、最初に CentOS のセットアップを行います。 まずは ようこそ 画面が表示されます。
centos_install51


CentOS のライセンス情報が表示されます。内容を確認します。
centos_install52


画面の左下に同意/不同意の選択肢が表示されています。 ライセンス内容に同意する場合は はい、ライセンス同意書に同意します にチェックを入れて先に進みます。
centos_install53


一般ユーザーの作成画面に移ります。 注意点として 一般ユーザーの作成は必須ではありません。 一般ユーザーを作成しなくても(常に root で利用するのであれば)このまま先に進むことができます。

今回の例では tuser というユーザーをここで作ることにして、その際の画面ショットを用意しました(作らなくてもかまいません)。
centos_install54


作成する一般ユーザーのパスワードが、いわゆる「弱いパスワード」の場合は警告メッセージが表示されます。 リスクを承知の上でこのまま指定したパスワードを使っても構いませんし、パスワードを変更することも可能です。
centos_install55


システム時刻の設定画面です。 年月日を指定し、必要であれば ネットワーク上で日付と時刻を同期化します にチェックを入れておきます (そうすると ntp が有効になります)。
centos_install56


Kdump の設定画面に移ります。 が、Kdump を有効にするにはある程度以上の空きメモリが必要です。充分なメモリがない場合は Kdump を有効にすることはできません。 その場合はこのようなダイアログが表示されます。
centos_install57


Kdump の設定画面はこのような内容です。Kdump を有効にする場合は kdump を有効にしますか? にチェックを入れておきます。
centos_install58


最後に 終了 ボタンをクリックして、このセットアップ内容をシステムに反映させます。
centos_install59


改めて GNOME 環境が起動し、ログイン画面が表示されます。

一般ユーザー(tuser)でログインする場合は、画面内の Test User と書かれた箇所をクリックすると パスワードの入力が求められます。
centos_install60


root ユーザーでログインする場合は、画面内の その他 と書かれた箇所をクリックし、 ユーザ名欄に root と入力して Enter キーを押します。
centos_install61


続いてパスワードを入力し、最後に Enter キーを押すか、ログイン ボタンをクリックします。
centos_install62


root ユーザーでログインしようとすると、システムへの変更も含めた影響から確認ダイアログが表示されます。 今後の表示が不要であれば 再度表示しない にチェックを入れ、閉じる ボタンをクリックします。
centos_install63


システムにログインして、GNOME のデスクトップ画面が表示されました。
centos_install64



 

3. CentOS の設定


 

導入したシステムは SELinux が有効になっているなど、セキュリティがある程度高めに設定されています。 安心して使える一方で、この後に導入するアプリケーションによっては設定が邪魔になることもあります。 ここでは比較的緩めのセキュリティ設定になるよう、変更する手順を紹介します。


3-1. SELinux の無効化

まずは 端末(ターミナル) を起動しましょう。画面左上の アプリケーション と書かれた 箇所をクリックし、システムツール - 端末 を選択します。
centos_install65


端末が起動しました。
centos_install66


以下は SELinux を無効にするための設定です。 有効にしたまま利用する場合、以下の操作は不要です。


まず現在の SELinux 設定状態を確認します。端末から getenforce と入力します。
# getenforce
Enforcing

実行結果の "Enforcing" は SELinux によるアクセス制限を行う設定状態になっていることを意味します。 これを一時的に無効にします。

# setenforce 0
# getenforce Disabled

実行結果の "Disabled" は SELinux によるアクセス制限を行わない設定状態になっていることを意味します。 とりあえず、これで SELinux は無効になりました。 しかしこの設定は一時的なもので、再起動は再び SELinux が有効になります。 再起動後も SELinux が無効になるようにするには、以下のファイルを編集します。

# vi /etc/selinux/config

(変更内容)SELINUX=disabled

設定後に再起動すると、setenforce コマンドなしに SELinux が無効の状態になります。

# shutdown -r now

3-2. IPv6 の無効化

IPv6 を利用しないのであれば、無効になるよう設定します。 まず 端末(ターミナル) を起動し、以下のファイルを新規に作成します。
# vi /etc/modprobe.d/disable_ipv6.conf

(ファイルの内容)
alias net-pf-10 off
options ipv6 disable=1

設定後に再起動します。

# shutdown -r now

再起動後は IPv6が無効の状態になり、ifconfig コマンドでも表示されなくなります。

# ifconfig | grep "inet6 addr"
#

3-3. 不要なサービス停止

無駄なリソースの消費を抑えるため、不要なサービスを停止します。以下は一例:
# ntsysv --level 345

[ ] NetworkManager (有線/無線のネットワーク設定をGUIで行うサービス)
[*] abrt-ccpp (自動バグ報告ツール)
[*] abrt-oops (不具合を oops トラッカーへ送信するサービス)
[*] abrtd (自動バグ方向ツール)
[ ] acpid (電源管理 ノートPC向け)
[ ] atd (任意コマンドを指定時間に1回実行するサービス)
[*] auditd (監査ログを出力するデーモン)
[ ] avahi-daemon (DNSを使わずにIPマルチキャストで名前やアドレスを参照するサービス)
[ ] cpuspeed (CPUの省電力機能 ノートPC向け)
[*] crond (任意コマンドを指定時間に繰り返し実行するサービス)
[ ] cups (印刷サービス)
[ ] dnsmasq (DNSとDHCPサービスを提供するサービス)
[ ] firstboot (インストール直後の初期セットアップ起動)
[*] haldaemon (ハードウェア情報を収集するサービス)
[ ] ip6tables (IPv6用パケットフィルタ)
[ ] iptables (IPv4用パケットフィルタ)
[*] irqbalane (マルチCPU環境での分散処理)
[ ] kdump (Kernelクラッシュ時のKernelダンプを保存する)
[*] lvm2-monitor (LVM関連サービス)
[*] mdmonitor (ソフトRAID監視サービス)
[*] messagebus (メッセージバスアプリケーション用)
[ ] netconsole (Kernelクラッシュ時のKernelダンプをネットワーク経由で保存する)
[ ] netfs (NFSクライアント)
[*] network (ネットワーク接続に関連するデーモン)
[ ] ntpd (NTPサービス)
[ ] ntpdate (他のサービスが起動前に正確な時刻を必要とするか、/etc/sysconfig/ntpd で -x オプションを指定した場合のみ有効にする)
[ ] portreserve ()
[*] postfix (SMTPサービス)
[ ] psacct (アカウントの利用統計を取得するサービス)
[ ] quota_nid (クォータ値超過が発生した旨のカーネルメッセージを D-BUS に転送する)
[ ] rdisc (ネットワークルータディスカバリーデーモン ルータとして動作させない場合は不要)
[ ] restorecond (SELinux 関連デーモン SELinuxを使わない場合は不要)
[*] rsyslog (システムログデーモン)
[ ] saslauthd (sas認証デーモン)
[*] smartd (HDD故障の予兆を検知するサービス)
[*] spice-vdagentd (デスクトップ仮想化デーモン)
[*] sshd (SSHサービス)
[*] sysstat (システム情報取得ツール)
[ ] udev-post (ハードウェア自動認識デーモン)
[ ] wdaemon (ハードウェア自動認識デーモン)
[ ] wpa_supplicant (無線LANクライアントとして WPA 暗号化をする場合に必要なサービス)

設定後に再起動します。これで不要サービスが停止します。

# shutdown -r now

3-4. パッケージアップデート

パッケージを最新版にアップデートします。
# yum update

更新が可能なパッケージが見つかった場合はインストールするかどうかを聞かれるので "y" を押します。

:

Total download size: 319M
Is this ok [y/N]: y
Downloading packages:

:

yum コマンドを導入後初めて実行する場合は GPG キーのインポートが必要、という警告/確認メッセージが表示されます。

:

警告: rpmts_HdrFromFdno: ヘッダ V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Importing GPG key 0xC105B9DE:
Userid : CentOS-6 Key (CentOS 6 Official Signing Key) <centos-6-key@centos.org>
Package: centos-release-6-2.el6.centos.7.x86_64 (@anaconda-CentOS-201112091719.x86_64/6.2)
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Is this ok [y/N]:

インストール直後は RPM パッケージの正当性をチェックする GPG キーがインポートされていないため、 確認メッセージが表示されます。"y" をクリックして更新を継続します。


カーネルアップデートは再起動後に有効になります。

# shutdown -r now

3-5. シェルの初期設定

このまま使い始めてもいいのですが、シェルを便利に使えるように設定します。以下は自分がやっている設定です。

まずは /etc/bashrc の最後に1行追加して、vim を vi にエイリアスします:
# vi /etc/bashrc
:
(以下を最後に追加)
alias vi='vim'

次に vim の設定を変更するため /etc/vimrc の最後に数行追加します:
# vi /etc/vimrc
:
(以下を最後に追加)
set nu
set ts=4
autocmd FileType * set formatoptions-=ro 

これで vi(vim) が少し使いやすくなりました。後は自分の好きなように。

Amazon EC2 インスタンスの負荷測定をどうやって行うべきか、という問題です。結論を先にいうと「EC2 インスタンスの場合は top コマンドではなく、CloudWatch を使うべき」ということになります。

きっかけは自分が先日ツイートしたこの現象に気付いたことでした:


EC2 で運用しているサーバーの CPU 負荷を測定すると、CloudWatch で測定した場合は80%超え(上図左)になってアラート出まくりなのに、直接ログインして top コマンドで測定するとせいぜい10%前後(上図右)になる、というものです。

なぜ測定方法によって負荷値が異なるのか? CPU 負荷の定義が違うのか? だとしたらどちらを信用すべきなのか、どちらかはそもそも信用してはいけないのか、・・・・

よくわからんなあ・・・ と思っていたのですが、ある日こんな情報を見つけました:
EC2 monitoring: the case of stolen CPU


簡単に言うと、「例えば CPU が 0.1 個割り当てられた仮想マシンでは、(topコマンドでの)CPU 負荷 = 10% の状態でその仮想マシンのCPU的には100%になっている」ということです。なので EC2 上の(Xen上の)仮想インスタンスを1台のマシンとみなして負荷を計測するのであれば CloudWatch を使うべき、ということになります。逆に言えばこの環境下での top コマンドの結果には注意が必要です。


上記ページには "If you’re an IBM cus­tomer with a pSeries frame these ques­tions aren’t entirely new to you"(IBM の pSeries の顧客であれば特別目新しいことではない) とも書かれてます。へぇ、AIX ってそうなんだ。知らなかったけどね・・・ :P


 

ワードプレス(WordPress)をよく使っています。個人でも業務でも。ブログというよりは、いわゆるCMS(コンテンツ管理システム)の機能を使ったサイトのプラットフォームとして利用することが多いです。まだまだですが、それなりに詳しくなってきたかなと自負しています。

CMS なのでファイルのアップロード機能などは普通に備えています。ただ「ワードプレスでファイルのアップロードができない」という質問は FAQ と化しています。ワードプレスでアップロードしたファイルはデータベースではなくファイルシステム内に格納(というか移動)されて保管されるのですが、この格納先ディレクトリはワードプレスの zip ファイルを展開しただけではできず、自分で wp-content/ フォルダの下に uploads/ という名前のサブディレクトリを作り、apache 等のウェブユーザーが書き込み可能な権限を設定する必要があります。大抵はこれで解決します。

そこまで設定しても「アップロードできない」ことはたまにあるようです。これもまだ FAQ といっていいレベルで、「WordPress アップロード エラー」あたりでググると、この問題に悩む人達がいかに多いかわかります。多くの場合はアップロードしようとすると「HTTP エラー。」というメッセージが表示されるようです。
wp_httperror00

原因はケース・バイ・ケースですが、プラグインの相性が悪いケースだとすると一度全てのプラグインを無効にしたら直ったとか、諦めて再導入したら直ったとか、色々試したけどそれでもまだ直らないとか、色んなケースがあるようです。特に注目したいのは最後のケースで、この問題は世に(ネットに)出回っている情報では解決出来ないケースが少なからずある、ということです。そういうのにぶち当たっちゃったら大変だよね・・・

なんて考えてたら、自分の所にも厄介なのがやってきました。何が厄介かって「以前は問題なくアップロードできていたのに、今アップロードすると100%失敗する」というもの。以前は動いていたんだから根本的な問題とは思えないが、今実際にアップロードすると常に「HTTP エラー。」になってしまいます。 念のためプラグインを全て無効にした上で試すなど、ウェブで見つけた情報を頼りに色々試してみましたが、解決には至りませんでした。


と、ここまでが今回のブログエントリの導入部です。ちょっとだけ WordPress に詳しくなった自分を試す意味も含めて、この「ググってもよくわからない」ケースを自力で解決すべく、WordPress の PHP デバッグを敢行してみました。以下はその結果として分かったことのまとめです。今回分かった原因と同じ原因で悩んでいる人がどれだけいるかわかりませんが、参考になれば。


まずは HTTPD のログをみます。アップロードが失敗するタイミングで /wp-admin/async-upload.php が HTTP コード 500 を返していることが分かりました。まずはこのファイルにデバッグライトを仕掛けて、、と。これを地道に繰り返して、どこでエラーが発生しているのかを特定していきます。
wp_httperror02

そして、エラー箇所をたどっていくと /wp-admin/includes/media.php 内の wp_read_image_metadata() 関数でエラーが発生していることを発見しました。
wp_httperror03

これ、WordPress のコア関数の1つなので、これがエラーと言われても・・・ と思いつつも、とりあえず Codex によると、この関数は /wp-admin/includes/image.php で定義されているようなのでこのファイルを開いて更にデバッグライトを埋め込んで・・・ 

ん?
wp_httperror01
 
なんと /wp-admin/includes/image.php のサイズが0バイト!そりゃここでコケるわな!


というわけで、今回の WordPress のファイルアップロードができない問題を自分の環境下で調査した結論としては、WordPress を構成するファイルの一部がたまたま壊れてしまっていたからでした。ファイルが壊れる原因は色々考えられるのですが、修正するには元のアーカイブなどから壊れる前の該当ファイルを取り出してコピーする、とかになると思います。それにしてもこれが原因だとすると、気付くのは結構たいへんだと思う・・・

そしてこういうことが起こっていると、ファイルアップロード時には(これも話をややこしくしてると思うけど)「HTTP エラー。」というエラーメッセージが表示される、ということも分かりました。このエラーメッセージはかなり汎用的に使われていて、必ずしも HTTP レベルでの問題とは思わないほうがいいかも。

なお、WordPress を導入したディレクトリから、
 # find . -size 0 -print
を実行すると、同じように何らかの原因でサイズがゼロになってしまったファイルの一覧を取り出すことができます。


WordPress のファイルアップロード時「HTTP エラー。」で悩んでいて、設定とかを見なおしたけどまだよく分からない、という場合は念のため調査してみるのもいいかもです。
 

このページのトップヘ