CoreOS&Docker環境においてOracle Database 11g Release 2をインストールするためのポイント

2016年3月23日(水)
世古 雅也
データベースの定番であるOracle Databse 11g Release 2を、コンテナ環境に導入する手順を紹介します。

はじめに

筆者はCoreOS&Docker上に、Oracle Database 11g Release 2 Standard Edition(以下、Oracle11gR2と表記)をインストールする検証を行った。その際、Oracle11gR2のインストールを成功させるためにはポイントが存在することが分かった。本稿では、このOracle11gR2をインストールするためのポイントについて解説する。なお本稿の想定読者は、CentOSにOracle11gR2をインストールした経験がある人とする。

本論に入る前に、本検証を行うことになった背景について軽く説明させていただきたい。弊社にはNablarch Application Frameworkという名称のJava用フレームワークが存在する。本フレームワークは多くのミドルウェアに対応しているため、様々なミドルウェアの組み合わせによるテストを行う必要がある。

機材の都合で、1台のホストに複数のミドルウェアをインストールする必要があるのだが、以下の問題に遭遇しているため、Dockerを検証することとした。

テストの際に生じた課題

遭遇した問題Dockerに期待すること
当初は複数バージョンで検証する予定がなかったミドルウェアについて、後から複数バージョンでの検証が必要になった際、ミドルウェアごとに環境変数やポートを切り替える方法がアドホックになりがちである。その結果、時間が経つにつれ、クリーンな環境を保つのが難しくなる環境変数などをコンテナに閉じ込められるため、クリーンな環境の維持が容易になる
上記の対策として、Xen等の仮想環境の使用も検討したが、将来的にIaaSに移行したいため、仮想環境の採用は足かせになる可能性がある。また、テストの際に起動と停止を頻繁に行うことが想定されるため、OSから起動しているとテストの実行時間が長くなってしまう恐れがある様々なIaaSで使用できるため、将来のIaaSへの移行が容易と思われる。また、起動が速いため、コンテナの起動と停止のせいでテストが遅れることがない
環境変数等の切り替えの都合により、通常とは異なる方法でのインストールを行いがちであるため、ミドルウェアのアンインストールが困難であり、不要になっても放置しがちになるコンテナとimageを破棄するだけで良いため、アンインストールが簡単になる
環境変数等の切り替えの都合により、通常とは異なる方法でのインストールを行いがちであるため、再インストールが必要になった際に、インストール方法が思い出せず多大な時間が掛かるDockerFileにインストール手順が記録されるため、再インストールが必要になった際に楽である

以下に、計画したテスト環境の構成図を示す。

最終的に構築したいテスト環境

最終的に構築したいテスト環境

※Dockerコンテナは一部のみ記載※各コンテナは、使用するときのみ起動する

環境構築に先立ち、いくつかのミドルウェアをコンテナ上で動作させる検証を行い、その対象の一つにOracle11gR2が存在した。Docker Hubを探したところ、Oracle Database Express Edition 11g Release 2をインストールするためのイメージやDockerfileは見つかったものの、Oracle Database 11g Release 2 Standard EditionをインストールするためのDockerfileは見つからなかったため、インストールの段階から検証することとしたのが、今回のテストの背景である。

検証を実施した環境

検証は以下の環境で行った。

  • さくらのクラウド
  • ホスト側のOS:CoreOS 766.5.0(さくらのクラウドで提供されている367.1.0からアップデート)
  • Docker:1.7.1
  • コンテナ側のOS:CentOS 6.6

作業の手順

作業は以下の手順で行った。

  1. さくらのクラウドでインスタンスを起動する
  2. CoreOS上で、「sudo update_engine_client -update」を実行し、CoreOSをアップデートする
  3. オラクル社のサイトからLinux x86-64用のOracle11gR2のインストーラをダウンロードする。Dokcer上で動作するイメージの多くは64bitOS用であるため、64bit用のインストーラを使用する。ダウンロードしたZIPファイルは、CoreOS上で展開しておく
  4. Oracle11gR2のレスポンスファイルとoraInst.locファイルを用意する。GUIのインストーラを使うためにはXの導入が必要になるため、今回はCLIでインストールする
  5. ホスト側の環境設定を行う。Dockerはカーネルをホストと共有するため、ホスト側でもカーネルのパラメータの設定を行っておく
  6. Dockerfileを用意する。Dockerfileには、Oracle11gR2のインストーラを起動するまでを記述する。Dockerfileにインストーラの起動を記述しないのは、以下の理由による。
    ・インストーラ実行中、「別のシェルを起動して、rootでスクリプトを実行する」ように求められる箇所があるが、この部分をDockerfileで実現するのは困難であるため
    ・Oracle11gR2のインストーラの実行条件を整える際に、特権モード(--privilegedオプション)が必要な箇所があるが、docker build実行時は特権モードを指定できないため
  7. docker buildを実行する。実行時には、Dockerfile、Oracle11gR2のインストーラ、レスポンスファイル、oraInst.locを同一ディレクトリに配置しておく
  8. docker runを実行する。この際、Oracle11gR2のインストーラ起動のために、必要な引数をつける必要がある
  9. コンテナ内で環境設定を行う。Oracle11gR2のインストーラ起動に必要である
  10. Oracle11gR2のインストーラを実行する
  11. コンテナの起動と同時に、Oracle11gR2を起動するための設定を行う
  12. コンテナを停止し、コンテナをdocker commitする
  13. 作成したimageを使用してOracle11gR2を起動と停止の確認を行う

本稿では、主に手順1、手順5から手順13について解説する。

さくらのクラウドでインスタンス起動

さくらのクラウドで起動するサーバは、以下のスペックを推奨する。

起動するサーバの推奨スペック

項目説明
CPU1コア以上仮想化によるオーバーヘッドはそれほど多くないため、1コアでもOracle11gR2は起動できる。必要に応じてコア数を決定すること
メモリ1GB以上CoreOSがデフォルトで/tmpに割り当てるサイズは、メモリの半分程度である。後述するが、Oracle11gR2の自動メモリ管理で使用するためにコンテナの/dev/shmに、ホストの/tmpを割り当てる。そのため、必要に応じて本サイズを決めること
ディスク40GB以上Oracle11gR2のDockerのImageは、10GB以上になることがある。Imageとコンテナで使用するディスク容量を踏まえると、40GB以上のディスクを使用した方が良い

ホスト側の環境設定

ホスト側では、以下の項目を設定する。

カーネルのパラメータ

Oracle11gR2のインストール要件を満たすために設定が必要である。カーネルのパラメータに対してチューニングを行う際、ホスト側とコンテナ側のどちらにカーネルのパラメータを設定する必要があるのか、Dockerのドキュメントから記述をみつけることができなかった。そのため、本稿ではホストとコンテナの双方に設定することとする。

スワップ領域

Oracle11gR2のイストーラー起動時の環境チェックに合格するために必要。検証の結果、ホストに設定したスワップ領域をコンテナが使用することが分かっているため、ホストにスワップ領域を割り当てる(CoreOSは、デフォルトではスワップ領域を割り当てない)。

CoreOSを使用したホストにカーネルのパラメータを設定する方法を、以下に示す。

/usr/share/oem/cloud-config.ymlを編集する

追記する内容の例は、以下の通りだ。

リスト1:

coreos:
  units:
    - name: systemd-modules-load.service
      command: restart
    - name: systemd-sysctl.service
      command: restart

write_files:
  - path: /etc/modules-load.d/nf.conf
    content: |
      nf_conntrack
  - path: /etc/sysctl.d/nf.conf
    content: |
        kernel.shmall = 1073741824
        kernel.shmmax = 536870912
        kernel.shmmni = 4096
        kernel.sem = 250 32000 100 128
        fs.file-max = 6815744
        fs.aio-max-nr = 1048576
        net.ipv4.ip_local_port_range = 9000 65500
        net.core.rmem_default = 262144
        net.core.rmem_max = 4194304
        net.core.wmem_default = 262144
        net.core.wmem_max = 1048576

ホストを再起動する

設定値の確認

/proc/sys/以下の値を表示して、設定値が有効になっていることを確認する。例えば、kernel.shmallの値を確認する際は以下のようになる。

リスト2:

$ cat /proc/sys/kernel/shmall
1073741824

CoreOSを使用したホストにスワップ領域を割り当てる方法を以下に示す。今回はディスク容量の都合で512MBを割り当てることとした。

ファイルの作成

スワップ領域として使用するためのファイルを作成する。

リスト3:

$ sudo fallocate -l 512m /512MiB.swap
$ sudo chmod 600 /512MiB.swap
$ sudo chattr +C /512MiB.swap
$ sudo mkswap /512MiB.swap

設定ファイルの作成

ホストOS起動時にスワップ領域をマウントするため、systemdの設定ファイルを作成する。設定ファイルは/etc/systemd/system/swap.serviceというファイル名で作成した。

リスト4:

[Unit]
Description=Turn on swap

[Service]
Type=oneshot
Environment="SWAPFILE=/512MiB.swap"
RemainAfterExit=true
ExecStartPre=/usr/sbin/losetup -f ${SWAPFILE}
ExecStart=/usr/bin/sh -c "/sbin/swapon $(/usr/sbin/losetup -j ${SWAPFILE} | /usr/bin/cut -d : -f 1)"
ExecStop=/usr/bin/sh -c "/sbin/swapoff $(/usr/sbin/losetup -j ${SWAPFILE} | /usr/bin/cut -d : -f 1)"
ExecStopPost=/usr/bin/sh -c "/usr/sbin/losetup -d $(/usr/sbin/losetup -j ${SWAPFILE} | /usr/bin/cut -d : -f 1)"

[Install]
WantedBy=multi-user.target

設定ファイルの有効化

作成した設定ファイルを有効化するために、以下のコマンドを実行する。

リスト5:

$ sudo systemctl enable swap.service

再起動

ホストを再起動する。

確認

再起動後、cat /proc/meminfoを実行してスワップ領域が割り当てられていることを確認する。SwapTotalの項に、割り当てたスワップファイルの容量が表示される。

リスト6:

$ cat /proc/meminfo
(中略)
SwapTotal:        524284 kB
SwapFree:         520796 kB

Dockerfileの準備

Dockerfileでは以下の処理を行う。1. ベースとなるイメージの指定。今回は、CentOS 6.6のオフィシャルイメージを使用することとした2. Oracle11gR2のインストールに必要なパッケージのインストール3. Oracle11gR2のインストールに必要なOSのユーザとグループの作成4. Oralce11gR2のインストール先ディレクトリの作成と権限付与5. インストーラ等のコンテナへのコピー

Oracle11gR2のインストールに必要となるパッケージは、「Oracle Databaseインストレーション・ガイド」の「Linux x86-64のOracle Databaseパッケージ要件」の項を参考に調査した。パッケージのインストール部分を、Dockerfileから抜粋する。

リスト7:

RUN \
yum -y install \
binutils \
compat-libcap1 \
compat-libstdc++ \
compat-libstdc++-33 \
compat-libstdc++-33.i686 \
gcc \
gcc-c++ \
glibc \
glibc-devel \
glibc.i686 \
ksh \
libgcc \
libstdc++ \
'libstdc++.so.5' \
libstdc++-devel \
libaio \
libaio-devel \
make \
sysstat

「Oracle11gR2のインストールに必要なOSのユーザとグループの作成」については、ちょっとしたテクニックが存在する。通常、対話なしにパスワードを設定したユーザを作成するには、暗号化済みのパスワードを作成しておいてそれをuseraddの引数に設定する。セキュリティ的に平文で保存しても構わない場合は、ユーザ作成後chpasswdでパスワードを設定することで、パスワードを平文で記述することが出来る。以下に、ユーザ作成とパスワード設定の例を示す。以下の例では、Oracleのホームディレクトリにインストールを行うため、所有者とパーミッションの設定も併せて行っている。

リスト8:

RUN \
groupadd oinstall && \
groupadd dba && \
groupadd oper && \
useradd -g oinstall -G dba,oper -d /opt/oracle -s /bin/bash oracle && \
echo 'oracle:oracle' | chpasswd && \
chown -R oracle:oinstall /opt/oracle && \
chmod -R 755 /opt/oracle

インストーラ等のコンテナへのコピーについては、いったんコンテナ内の作業用ディレクトリにコピーしたのちに、必要なものについてはさらに別の場所にコピーしている。いったん作業用ディレクトリにコピーする必然性はないが、その方がDockerfileの構造についてわかりやすく感じるため、そのようにした。

リスト9:

ADD database /data/database/
ADD db_install.rsp /data/
RUN chmod 777 -R /data/

RUN \
cp /data/oraInst.loc /etc && \
chown oracle:oinstall /etc/oraInst.loc && \
chmod 664 /etc/oraInst.loc

docker buildの実行

Dockerfile、Oracle11gR2のインストーラ、レスポンスファイル、oraInst.locを一つのディレクトリに揃えたのち、docker buldを実行する。以下にコマンドの例を示す。

リスト10:

$ ls
Dockerfile  database  db_install.rsp  oraInst.loc
$ docker build -t oracle11g .

docker runの実行

イメージの作成が終わったら、docker runでコンテナを起動する。起動時に、以下の環境設定を行う。

Dockerの特権モードを指定

コンテナ内でのmountコマンドの実行および、カーネルのパラメータを書き換える際に必要となる。

プロセス数のリミットの設定

Oralceの推奨設定を満たすために設定する必要がある。docker run時にrootユーザ用の設定を行う。Docker 1.6からは、--ulimitオプションで設定可能になった。

/dev/shmの割り当て

Oracleの自動メモリ管理を使用する際に必要な設定である。

「/dev/shmの割り当て」について補足する。コンテナの/dev/shmにはデフォルトで64MBが割り当てられているが、これではOracle11gR2の自動メモリ管理を使用するためには小さすぎる。

コンテナの/dev/shmを増やすためには、ファイルシステムが「tmpfs」となっているホストのディスク領域を割り当てる。ファイルシステムの確認のために、ホストでdfコマンドを実行した結果を以下に示す。

リスト11:

$ df -hT
Filesystem     Type      Size  Used Avail Use% Mounted on
rootfs         rootfs     38G   17M   38G   1% /
devtmpfs       devtmpfs  489M     0  489M   0% /dev
tmpfs          tmpfs     500M     0  500M   0% /dev/shm
tmpfs          tmpfs     500M  224K  499M   1% /run
tmpfs          tmpfs     500M     0  500M   0% /sys/fs/cgroup
/dev/vda9      btrfs      38G   17M   38G   1% /
/dev/vda3      ext4     1008M  288M  670M  31% /usr
tmpfs          tmpfs     500M     0  500M   0% /tmp
tmpfs          tmpfs     500M     0  500M   0% /media
/dev/vda6      ext4      108M   56K   99M   1% /usr/share/oem

/tmpがtmpfsなので、コンテナの/dev/shmをそこに割り当てることとする。

環境設定を行った状態でのdocker runのコマンド例は以下の通りである。

リスト12:

$ docker run --privileged --ulimit nproc=2047:16384 --name oracle11g -v /tmp:/dev/shm -it oracle11g sh

コンテナ内の環境設定

docker runでコンテナを起動後、コンテナ内で以下の設定を行う。

  • カーネルパラメータの設定
  • インストールに使用するユーザ(oracleユーザ)に対する、プロセス数のソフトリミットの設定

カーネルパラメータは、通常は/proc以下に値を書き込めないため設定できない。/proc以下に値を書き込むには二つ方法が存在する。

  1. /procを読み書き可能として再マウントする
  2. ホストの適当なディレクトリを/procとしてマウントする

今回は、項番1の方法でカーネルパラメータの設定を行った。以下にカーネルパラメータの設定のためのコマンドを示す。

リスト13:

# mount -o remount,rw -t proc /proc /proc
# echo 250 32000 100 128 > /proc/sys/kernel/sem
# echo 128 > /proc/sys/kernel/shmmni
# echo 536870912 > /proc/sys/kernel/shmmax
# echo 2097152 > /proc/sys/kernel/shmall
# echo 9000 65500 > /proc/sys/net/ipv4/ip_local_port_range

docker run時の--ulimit引数で設定したプロセス数のソフトリミットは、コンテナに入った後、suで切り替えたユーザには値が引き継がれない。インストール前にoracleユーザに切り替えるため、再設定が必要となる。以下にoracleユーザに切り替えた後、ソフトリミットを設定するためのコマンドを示す。

リスト14:

# su - oracle
$ ulimit -S -u 2048

Oracle11gR2のインストーラの実行

Oracle11gR2のインストーラを起動する前に、database/stage/cvu/cvu_prereq.xmlのRUNLEVELの設定を編集する。これは、Oracle11gR2のインストーラがランレベルを厳格にチェックし過ぎるためである。インストーラが存在するディレクトリに移動して、以下のコマンドを実行する。

リスト15:

$ sed -i -e 's/<RUNLEVEL>/<RUNLEVEL SEVERITY="IGNORABLE">/g' stage/cvu/cvu_prereq.xml

Oracle11gR2のインストーラは、以下の例のようにレスポンスファイルのパスを指定して起動する。

リスト16:

$ ./runInstaller -silent  -responseFile /data/db_install.rsp

インストーラ実行中、以下のメッセージが表示される。その際には、別のコンソールからdocker execコマンドでコンテナに入って、メッセージ中で指定されているスクリプト(/opt/oracle/product/11.2/root.sh)を実行しよう。

リスト17:

The following configuration scripts need to be executed as the "root" user.
 #!/bin/sh
 #Root scripts to run

/opt/oracle/product/11.2/root.sh
To execute the configuration scripts:
         1. Open a terminal window
         2. Log in as "root"
         3. Run the scripts
         4. Return to this window and hit "Enter" key to continue

インストーラの実行終了までには、筆者の環境で30分前後掛かった。インストール中に問題があった場合には、「<インベントリのディレクトリ>/logs/」に存在するログを確認すると良い。インベントリのディレクトリは、レスポンスファイル内でINVENTORY_LOCATIONというキーで指定しているはずである。

Oracle11gR2起動の設定

起動の設定として以下を行う。

  • /etc/oratabと/etc/rc.d/init.d/dboraの準備
  • docker run 時に実行するシェルスクリプトの実装

自動起動を有効にするために、/etc/oratabを編集する。以下のように最終行の末尾の「N」を「Y」にする。

リスト18:

#

# This file is used by ORACLE utilities.  It is created by root.sh
# and updated by the Database Configuration Assistant when creating
# a database.

# A colon, ':', is used as the field terminator.  A new line terminates
# the entry.  Lines beginning with a pound sign, '#', are comments.
#
# Entries are of the form:
#   $ORACLE_SID:$ORACLE_HOME:<N|Y>:
#
# The first and second fields are the system identifier and home
# directory of the database respectively.  The third filed indicates
# to the dbstart utility that the database should , "Y", or should not,
# "N", be brought up at system boot time.
#
# Multiple entries with the same $ORACLE_SID are not allowed.
#
#
xe:/opt/oracle/product/11.2:Y

/etc/rc.d/init.d/dboraは、Oracle Database管理者リファレンスを参考に、以下のように実装した。ポイントは、dbstart実行前に、プロセス数のソフトリミットを設定することである(ハードリミットはコンテナ起動時に毎回設定するか、dockerデーモン起動時に設定しておく)。

リスト19:

#! /bin/sh  -x
#
# Change the value of ORACLE_HOME to specify the correct Oracle home
# directory for your installation.

ORACLE_HOME=/opt/oracle/product/11.2
#
# Change the value of ORACLE to the login name of the
# oracle owner at your site.
#
ORACLE=oracle

#
case $1 in
'start')
        su - $ORACLE -c "ulimit -S -u 2048 && ${ORACLE_HOME}/bin/dbstart ${ORACLE_HOME}"
        ;;
'stop')
        su - $ORACLE -c "${ORACLE_HOME}/bin/dbshut ${ORACLE_HOME}"
        ;;
*)
        echo "usage: $0 {start|stop}"
        exit
        ;;
esac
#
exit

実装後は、rootユーザで実行できるように権限を付与する。以下に例を示す。

リスト20:

# chmod u+x /etc/rc.d/init.d/dbora

docker run時に実行するシェルスクリプトでは、以下の処理を行う。

カーネルのパラメータの設定

カーネルのパラメータは、dockerのimageに記録されないため、コンテナ起動時に毎回設定する。

listener.oraに含まれるホスト名の置換

コンテナ起動時にホスト名が決まるため、listener.oraに記載されているホスト名に置換する。

Oracle11gR2の起動処理

docker stop時にOracle11gR2を停止する設定

docker stop時、dockerはフォアグラウンドのプロセスにしかシグナルを送らない。そのため、フォアグラウンドのプロセスがシグナルを受信したらOracle11gR2を停止するように実装を行う。この設定をしない場合は、コンテナ停止前に手動でOracle11gR2を停止する必要がある

以下に実装例を示す。

リスト21:

#!/bin/sh
mount -o remount,rw -t proc /proc /proc
echo 250 32000 100 128 > /proc/sys/kernel/sem
echo 4096 > /proc/sys/kernel/shmmni
echo 536870912 > /proc/sys/kernel/shmmax
echo 2097152 > /proc/sys/kernel/shmall
echo 9000 65500 > /proc/sys/net/ipv4/ip_local_port_range

sed -i -E "s/HOST = [^)]+/HOST = $HOSTNAME/g" /opt/oracle/product/11.2/network/admin/listener.ora
chown oracle:oinstall /opt/oracle/product/11.2/network/admin/listener.ora
/etc/rc.d/init.d/dbora start
trap "/etc/rc.d/init.d/dbora stop && exit" SIGTERM
while true
do
    sleep 10
done

実装後は、rootユーザで実行できるように権限を付与する。以下に例を示す。

リスト22:

# chmod u+x /root/start.sh

また、oracleユーザの.bash_profileについても編集しておく。以下に例を示す。

リスト23:

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

export ORACLE_BASE=/opt/oracle
export ORACLE_HOME=$ORACLE_BASE/product/11.2
export ORACLE_SID=xe
export PATH=$PATH:$ORACLE_HOME/bin
export LD_LIBRARY_PATH=$ORACLE_HOME/lib

コンテナの停止とdocker commit

コンテナ内で各種設定が終わったら、インストール時に自動的に起動したOracle11gR2を停止したのちに、コンテナを停止する。以下にOracle11gR2の停止とコンテナの停止を行うコマンドの例を示す。

リスト24:

$ export ORACLE_BASE=/opt/oracle
$ export ORACLE_HOME=$ORACLE_BASE/product/11.2
$ export ORACLE_SID=xe
$ export PATH=$PATH:$ORACLE_HOME/bin
$ export LD_LIBRARY_PATH=$ORACLE_HOME/lib
$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.1.0 Production on Sat Nov 21 13:13:49 2015

Copyright (c) 1982, 2009, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Release 11.2.0.1.0 - 64bit Production

SQL> SHUTDOWN IMMEDIATE
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> exit
$ exit ← oracleユーザでのexit
# exit ← rootユーザでのexit

コンテナ起動時にshを指定しているはずなので、rootユーザでexitを実行した際に、シェルと同時にコンテナが終了するはずである。

コンテナを停止したらimageをコミットする。コミットする際には、コンテナ開始時に起動するスクリプトも併せて指定する。以下にコマンドの例を示す。

リスト25:

$ docker commit --change 'CMD ["/root/start.sh"]' oracle11g oracle11g

コミットをしたら、imageが保存されていることを確認するために「docker images」を実行する。

リスト26:

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
oracle11g           latest              f5dd49b35162        24 hours ago        11.1 GB
centos              6.6                 12c9d795d85a        5 weeks ago         202.6 MB

作成したimageを使用してのOracle11gR2の起動と停止

コミットしたimageを使用してコンテナを起動する際はdocker runを使用する。oracle11gR2の起動と、プロセスの起動を確認した際の例を示す。

リスト27:

$ docker run --privileged --name oracle11g -d -p 1521:1521 -v /tmp:/dev/shm -it oracle11g
a08af9dde97c54478a59ce0966b9186e46591bc1f3c1587b409fc0d9093dde92
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                              NAMES
a08af9dde97c        oracle11g           "/root/start.sh"    4 seconds ago       Up 3 seconds        0.0.0.0:1521->1521/tcp             oracle11g
$ ps aux | grep ora.*xe.*
core     14762  0.0  4.6 612512 47464 ?        Ss   15:15   0:00 ora_pmon_xe
core     14764  0.0  3.8 610268 39808 ?        Ss   15:15   0:00 ora_vktm_xe
core     14768  0.0  3.8 610268 39732 ?        Ss   15:15   0:00 ora_gen0_xe
core     14770  0.0  3.8 610268 39776 ?        Ss   15:15   0:00 ora_diag_xe
core     14772  0.0  6.1 610268 62340 ?        Ss   15:15   0:00 ora_dbrm_xe
core     14774  0.0  4.0 610268 41492 ?        Ss   15:15   0:00 ora_psp0_xe
core     14776  0.0  4.4 610780 45084 ?        Ss   15:15   0:00 ora_dia0_xe
core     14778  0.0  4.4 610268 45772 ?        Ss   15:15   0:00 ora_mman_xe
core     14780  0.0  4.6 616148 47616 ?        Ss   15:15   0:00 ora_dbw0_xe
core     14782  0.0  4.6 625820 47360 ?        Ss   15:15   0:00 ora_lgwr_xe
core     14784  0.0  4.4 610780 45592 ?        Ss   15:15   0:00 ora_ckpt_xe
core     14786  0.0  6.7 610784 69048 ?        Ss   15:15   0:00 ora_smon_xe
core     14788  0.0  6.2 610780 63720 ?        Ss   15:15   0:00 ora_reco_xe
core     14790  0.2 11.0 616060 112480 ?       Ss   15:15   0:00 ora_mmon_xe
core     14792  0.0  4.6 610268 47976 ?        Ss   15:15   0:00 ora_mmnl_xe
core     14794  0.0  3.8 616392 39504 ?        Ss   15:15   0:00 ora_d000_xe
core     14796  0.0  3.6 611332 36908 ?        Ss   15:15   0:00 ora_s000_xe
core     14826  0.0  4.2 610268 43432 ?        Ss   15:16   0:00 ora_qmnc_xe
core     14907  0.1  9.8 614876 100744 ?       Ss   15:16   0:00 ora_cjq0_xe
core     14936  0.0  6.7 610776 69272 ?        Ss   15:16   0:00 ora_q000_xe
core     14938  0.0  4.7 610264 49004 ?        Ss   15:16   0:00 ora_q001_xe
core     14964  0.0  0.0   4404   776 pts/0    S+   15:17   0:00 grep --colour=auto ora.*xe.*

上記の手順で起動しない場合は、以下の点を確認しよう。

/tmp内の確認

ホストの/tmpに、「ora」から始まる名前のファイルが大量に存在していないか確認する。Oracle11gR2が異常終了した際、/tmpにゴミが残るため/tmpの空きが不足して起動に失敗することがある。

エラーメッセージの確認

docker run時にshを指定して起動し、コンテナに入ってからスタートアップスクリプトを実行して、何かエラーメッセージが表示されていないか確認する。以下に実行例を示す。

リスト28:

$ docker run --privileged --name oracle11g -p 1521:1521 -v /tmp:/dev/shm -it oracle11g sh
# /root/start.sh

停止はホスト上でdocker stopを実行する。この際に-tオプションを指定してタイムアウト時間を長めに指定する必要がある。デフォルトでは10秒で強制終了してしまうためである。以下にタイムアウトを120秒にする例を示す。

リスト29:

$ docker stop -t 120 oracle11g

満たせていないインストール要件について

今回のテストでは、Oracle11gR2のインストール要件のうち、以下のカーネルパラメータについては設定できていない。

  • net.core.rmem_default
  • net.core.rmem_max
  • net.core.wmem_default
  • net.core.wmem_max

おそらくDockerのネットワーク機能の都合で設定できないと思われるのだが、詳細は不明である。

まとめ

CoreOS&Docker環境へのOracle11gR2のインストールは可能であった。このことから、フレームワークの動作確認を行うという目的は達成と言える。

一方、問題解決については、うまく出来たことと、出来なかったことがあった。以下に振り返りを記載する。

振り返り

Dockerに期待すること達成状況説明
環境変数などをコンテナに閉じ込めることができるため、クリーンな環境の維持が容易になる環境変数、ディレクトリ、ポートはコンテナに閉じ込めることが出来たため、ほぼ実現できた。しかし、カーネルパラメータについてはホストへの設定要否について謎が残った。ただし、カーネルパラメータについては、使用するDBの最小公倍数的な設定を行い、「DBはDB専用のホストで起動する」と割り切ってしまえば大きな問題はないと思われる
様々なIaaSで使用できるため、将来のIaaSへの移行が容易と思われる。また、起動が速いため、コンテナの起動と停止のせいでテストが遅れることがない今回さくらのクラウド上でCoreOS&Dockerを使用したが、特に問題は感じなかった。また、Dockerコンテナ起動も高速であり期待通りであった。
直接Dockerとは関係ない気付きであるが、ホスト側OSに採用したCoreOSの起動は大変高速で、ホスト側の再起動が必要になった際も快適であった
コンテナとimageを破棄するだけで良いため、アンインストールが簡単になるミドルウェアのアンインストールについては、「docker rm」と「docker rmi」を実行すれば終わるため、期待通り簡単に行える。一方、操作ミスでうっかり消してしまわないように、大事なimageはバックアップを取得するか、Dockerプライベートリポジトリにコミットする等の工夫を行ったほうが良い。
DockerFileにインストール手順が記録されるため、再インストールが必要になった際に楽であるDockerFileで全てを表現できないこともあるため、インストール手順を全てDockerFileに記録しておくことは出来なかった。一般的な対話式コマンドについてはexpectの使用で対応できるが、今回のように対応できないパターンのこともある。またdocker build時は特権モードを使用できないため、mountの実行が出来ないなど、いくつか制約が存在する
最初に期待していたメリットではないが、実は環境構築を何度もやり直すことになったため、途中までであってもDockerfileに手順を記録しておけるのは大変便利であった

その他、以下の注意点が存在することに気付いた。

ディスク容量

イメージサイズが大きくなりがちであるため、ディスク容量に注意が必要である。docker imagesで確認したところVIRTUAL SIZEの項が10GB前後であった。

インストール要件

前述したとおり、ネットワーク関連でパラメータについて、満たせていないインストール要件が存在するため、性能に悪影響が生じる可能性を否定できない。そのため、性能にシビアさが求められる本番環境で使用する際には、要件を満たせるか検証が必要である。また、連載「より深くDockerを知る」の「Dockerコンテナのパフォーマンス劣化とチューニング」であったように、ネットワークの速度とディスクの速度のチューニングにも気を付けた方が良いと思われる。

また、本稿を読んでOracle11gR2のインストールを行われる方は、オラクル社のライセンスポリシーを確認した上で行うように注意していただきたい。

今後の課題

本稿に関連して、今後の検証が必要と思われる課題は以下の通りだ。

docker pouse/unpouseへの対応

シグナルのtrapを追加することで対応できると思われるが、未検証である。

データファイル等をホスト側ディレクトリへ格納する設定

実現のためには、Oracle11gR2のOptimal Flexible Architectureを理解したうえで、ディレクトリ構成を設計する必要がある。

TIS株式会社

生産革新本部 アプリケーション開発センター所属。
システムエンジニアとして、数多くのシステム開発と、複数のJavaフレームワーク開発の案件を担当。
現在は、Javaアプリケーション開発/実行基盤「Nablarch」の開発を担当しており、製品の改善と利用の拡大に向けての技術情報の提供や利用者支援の活動に従事している。
「雑談でも技術ネタが出てくる」ような技術者集団の中で、楽しく業務を行っている。
> TIS株式会社

連載バックナンバー

運用・管理

事例から考えるDockerの本番利用に必要なこと

2016/5/26
本番環境へのDockerの導入が進むために必要な条件を、各社の事例を元に考察する。
運用・管理技術解説

Dockerコンテナ環境のバックアップツール「Convoy」を使う

2016/3/30
Docker環境のバックアップツールとして注目されるConvoyのインストールから使用方法までを解説します。
運用・管理技術解説

CoreOS&Docker環境においてOracle Database 11g Release 2をインストールするためのポイント

2016/3/23
データベースの定番であるOracle Databse 11g Release 2を、コンテナ環境に導入する手順を紹介します。

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています