#chiroito ’s blog

Java を中心とした趣味の技術について

Oracle公式Java実行環境のDockerイメージを構築

概要

Oracle 社の公式の Docker の設定ファイルが Github 上で公開されています。
github.com

設定ファイルには様々な製品の物が含まれていますが、今回はこれを使用して Oracle Java の実行環境を構築します。

作業

設定ファイルと Java のサーバランタイムをダウンロードします。次にサーバランタイムを適切な箇所に移動して、Docker イメージを作成します。最後に作成したイメージで Java が使えるか確認します。

Github から docker-images を落とします。git コマンドでも良いですし、ブラウザからZIPファイルをダウンロードも出来ます。docker-images のディレクトリを移行は IMAGES_HOME とします。

Java のサーバランタイムを次のリンクからダウンロードします。
http://www.oracle.com/technetwork/java/javase/downloads/index.htmlwww.oracle.com
サーバランタイムは Server JRE です。バージョンは今日時点での最新版である 8 update 112、プラットフォームは Linux x64 をダウンロードします。ダウンロードされるファイル名は server-jre-8u112-linux-x64.tar.gz となります。

ダウンロードしたファイルを $IMAGES_HOME/OracleJava/java-8 へ移動します。

ここまでの作業で準備完了です。$IMAGES_HOME/OracleJava/java-8 へ移動して OracleJavaのイメージを作成するシェルを実行します。
$ ./build.sh

Sending build context to Docker daemon 59.91 MB
Step 1 : FROM oraclelinux:latest
latest: Pulling from library/oraclelinux
0c333d7e75d2: Pull complete
Digest: sha256:f6cc386e1cc9d6702a67a3be885ddb70a30b0cdafc13d239f5b9ae55f76488ca
Status: Downloaded newer image for oraclelinux:latest
 ---> 4ee18f43f945
Step 2 : MAINTAINER Bruno Borges <bruno.borges@oracle.com>
 ---> Running in d72c4a866da2
 ---> 73e2c75dddd2
Removing intermediate container d72c4a866da2
Step 3 : ENV JAVA_PKG server-jre-8u*-linux-x64.tar.gz JAVA_HOME /usr/java/default
 ---> Running in 4f877a4c9d01
 ---> 9362ed2dcc29
Removing intermediate container 4f877a4c9d01
Step 4 : ADD $JAVA_PKG /usr/java/
 ---> 3a6dd166fd2f
Removing intermediate container 5c3979416bc7
Step 5 : RUN export JAVA_DIR=$(ls -1 -d /usr/java/*) &&     ln -s $JAVA_DIR /usr/java/latest &&     ln -s $JAVA_DIR /usr/java/default &&     alternatives --install /usr/bin/java java $JAVA_DIR/bin/java 20000 &&     alternatives --install /usr/bin/javac javac $JAVA_DIR/bin/javac 20000 &&     alternatives --install /usr/bin/jar jar $JAVA_DIR/bin/jar 20000
 ---> Running in eccc46eebc49
 ---> baadd9279b4b
Removing intermediate container eccc46eebc49
Successfully built baadd9279b4b

Successfully と出れば構築完了です。次は構築された Java を試すために Java のバージョンを確認するイメージを作成します。Dockerfile は次の通りです。java-8 のディレクトリには既に Dockerfile があるため別のディレクトリに移動してから Dockerfile を作りましょう。
$ vim Dockerfile

FROM oracle/serverjre:8
CMD ["java","-version"]

ビルドして Docker イメージを作成したら実行してみます
$ docker build -t jversion .

Sending build context to Docker daemon 4.096 kB
Step 1 : FROM oracle/serverjre:8
 ---> baadd9279b4b
Step 2 : CMD java -version
 ---> Running in 08ab54ae95b0
 ---> c50444f69864
Removing intermediate container 08ab54ae95b0
Successfully built c50444f69864

$ docker run -i jversion

java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)

ダウンロードしたバージョン番号が出力されているば確認完了です。次回は、実際に簡単なアプリケーションを書いて動かしてみます。

Kitematic でリモートの Docker Engine を管理する

概要

Windows を使っているので GUI で Docker を操作できる Kitematic を使って見たら、Virtualbox 上で仮想マシンを自動で構築してくれてるため非常に便利そうでした。しかし、日常で VPN 接続したりプロキシを切り替えたりしないといけないため、自動で作られる環境では融通が利かなかったので非常に困ってしまいました。

そのため、他の Docker Engine を管理する方法を調査してみました。

自分で構築した環境に Docker を入れて、Kitematic で管理することに成功したので、記録しておきます。

環境

調査

Kitematic のソースを見ると、どうやら Docker Machine を使用してマシンの操作をしているようです。

github.com

調べていくと以下の 2 点を抑えればいけそうです。
* default という名前の Docker Machine の設定を取得している。
* VirtualBox 上に default という名前の仮想マシンが無いと、Docker Machine 経由で作成する。

両方とも名前が default なので紛らわしいですが…

作業

リモートに Docker 環境はなく、今後しばらくは使うこともないと思うので、Oracle Linux仮想マシンVirtualBox 上に作成して、Docker Machine で環境構築することにしました。
この仮想マシンの名前を default として、Docker Machine にも default として登録しています。

VitualBox に default という名前の仮想マシンを作成します。
f:id:chiroito:20161105002229p:plain

Docker Machine で default という名前で環境を作成します。 手順はこちらを参照下さい。
chiroito.hatenablog.jp

以下の様な感じで作成してます。
$ docker-machine ls

NAME      ACTIVE   DRIVER    STATE     URL                         SWARM   DOCKER    ERRORS
default   -        generic   Running   tcp://192.168.56.10:2376           v1.12.3

あとはKitematic を起動するだけです。 f:id:chiroito:20161105005339p:plain

一回目の Checking Docker は失敗するので [USE VIRTUALBOX] を選択します。

f:id:chiroito:20161105005521p:plain

手探りでやっている時は良く分からなかったですが、ソースコードを見たら直ぐに分かったので、ソースが公開されているって便利ですね。

Docker Machine で Oracle Linux 上に Docker 環境を構築する

概要

Docker の環境を用意するのは docker をインストールするだけではなく、リモート接続できるようにしたり TLS 通信を出来るようにしたりなど様々な作業が必要となります。Docker Machine を使うことで簡単な作業だけで環境を構築できるようになります。
Docker Machine は様々な環境が用意されており、ローカルで使うだけでしたら Virtualbox 用に環境を作ってくれるため、Docker を試してみるには非常に便利です。今回は、Docker Machine を使用して Oracle Linux 上に環境を構築します。

事前に、OS をインストールしただけの Oracle Linux マシンを用意します。次に、このマシンにDocker Machine を使用するための準備を行い、最後にDocker Machine を実行して環境を構築します。

環境

  • Docker クライアント
  • Docker サーバ
    • Oracle Linux 7 update 2
    • SSH で接続するユーザ:user1
    • IP アドレス:192.168.56.10

サーバの事前準備

Docker Machine で環境を行う対象で、UEKのバージョンアップ、SSH 鍵の作成と設定、sudo 権限の付与をします。

Docker を使うにはデフォルトのカーネルである UEK 3 から UEK 4 へアップグレードしなければなりません。次に、SSH 接続する為にパスフレーズ無しの鍵を作成し、SSH 接続に使えるようにします。最後に SSH で接続するユーザに sudo 権限を付与して yum など管理者しか実行できないコマンドを使用できるようにします。

UEK 4 へアップデート

OL 7u2 では UEK 3.8 がインストールされているので、docker を使うために 4.1.12 へアップデートします。最新の yum リポジトリのファイルをダウンロードした後に UEK 4.x を有効化します。UEK を更新した後は OS を再起動します。

作業についてはこちらをご確認下さい。
chiroito.hatenablog.jp

鍵の作成と配置

Oracle Linux では、標準で鍵認証が有効になっているため、鍵を作成して配置するだけで鍵認証が行えます。今回は user1 というユーザで接続します。
まずは、SSH の鍵認証で使用する鍵を作成します。
ssh-keygen -t ed25519

Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user1/.ssh/id_ed25519): 
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user1/.ssh/id_ed25519.
Your public key has been saved in /home/user1/.ssh/id_ed25519.pub.
The key fingerprint is:
xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx user1@localhost
The key's randomart image is:
+--[ED25519  256--+
(略)
+-----------------+

鍵認証のために鍵を配置します。
cat .ssh/id_ed25519.pub >> .ssh/authorized_keys
chmod 700 .ssh
chmod 600 .ssh/authorized_key
ここで作成した鍵(id_ed25519とid_ed25519.pub)は Docker Machine を実行するクライアント側へコピーします。

sudo権限の付与

環境構築時に実行されるコマンドを user1 が実行できるように設定します。今回は全てのコマンドをパスワード無しで sudo 出来るようにします。
vim /etc/sudoers.d/docker

user1 ALL=NOPASSWD: ALL

今回は sudo で全てのコマンドを実行できるように指定していますが、細かく設定したい場合には以下のソースコードを参考にして下さい。
github.com

Docker Machine の実行と確認

事前準備が完了した Oracle Lnux マシンを docker-machine に登録します。このマシンのIPアドレスは 192.168.56.10で、作成した鍵(id_ed25519とid_ed25519.pub)が置いてあるディレクトリで以下のコマンドを実行します。
$ docker-machine create --driver generic --generic-ip-address=192.168.56.10 --generic-ssh-key id_ed25519 --generic-ssh-user user1 default

Running pre-create checks...
Creating machine...
(default) Importing SSH key...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with ol...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env default

Errorが出た場合には、デバッグオプション-Dを付けて実行することでより詳細なエラーが出力されます
docker-machine -D create <続く引数>

追加された docker-machine を確認

$ docker-machine ls

NAME      ACTIVE   DRIVER    STATE     URL                         SWARM   DOCKER    ERRORS
default   -        generic   Running   tcp://192.168.56.10:2376           v1.12.3

環境変数の取り込み

Docker Machine に複数登録していると環境変数を自分で変更するのは非常に面倒臭いです。Docker Machineをenvオプションを付けて実行することで環境変数の一覧と取り込みようスクリプトが出力されます。
docker-machine env default

SET DOCKER_TLS_VERIFY=1
SET DOCKER_HOST=tcp://192.168.56.10:2376
SET DOCKER_CERT_PATH=C:\Users\user1\.docker\machine\machines\default
SET DOCKER_MACHINE_NAME=default
REM Run this command to configure your shell:
REM     @FOR /f "tokens=*" %i IN ('docker-machine env default') DO @%i

最後の行が取り込みようスクリプトです。これを実行するだけで環境変数が適用されます。
@FOR /f "tokens=*" %i IN ('docker-machine env default') DO @%i

確認

環境変数の取り込みをしていれば、オプションを指定せずに Docker を実行できます。
docker run hello-world

Hello from Docker!
(略)

ダメだったこと

Docker Machine を実行したら途中で終わってしまったので、下記の様にデバッグオプション-Dを有効にしてみました。
$ docker-machine -D create --driver generic --generic-ip-address=192.168.56.10 --generic-ssh-key id_ed25519 --generic-ssh-user user1 default

出力されたログを確認するとパッケージの更新sudo -E yum -y updateで依存関係が衝突したため終わっていることが分かりました。

OS に入って下記のコマンドを実行して解決しました。
yum -y update --skip-broken

参考: docs.docker.com