#chiroito ’s blog

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

Oracle Linux 7u2 に UEK 4 をインストール

概要

OL 7u2 では、UEK 3.8 がインストールされているので、UEK を 4.1.12 へアップデートします。yumリポジトリファイルを最新化してから UEK をアップデートします。

環境

リポジトリファイルの更新

最新の yum リポジトリのファイルをダウンロードし、UEK 3 のリポジトリを無効化、UEK 4 のリポジトリを有効化します。

yum リポジトリのファイルを最新版をダウンロードします。
$ cd /etc/yum.repos.d/
$ rm -f public-yum-ol7.repo
$ wget http://yum.oracle.com/public-yum-ol7.repo

UEK 3.x ではなく UEK 4.x を使うように変更します。enabled=1が有効で、enabled=0が無効です。
$ vim public-yum-ol7.repo

[ol7_UEKR4]
name=Latest Unbreakable Enterprise Kernel Release 4 for Oracle Linux $releasever ($basearch)
baseurl=http://yum.oracle.com/repo/OracleLinux/OL7/UEKR4/$basearch/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-oracle
gpgcheck=1
#enabled=0
enabled=1

[ol7_UEKR3]
name=Latest Unbreakable Enterprise Kernel Release 3 for Oracle Linux $releasever ($basearch)
baseurl=http://yum.oracle.com/repo/OracleLinux/OL7/UEKR3/$basearch/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-oracle
gpgcheck=1
#enabled=1
enabled=0

カーネルの更新

UEK をアップデートし、OS を再起動します。

カーネルを更新して再起動します。
$ yum update kernel-uek
$ reboot

UEK が更新されたことを確認します。
$ uname -r
4.1.12-61.1.16.el7uek.x86_64

TLS を使用して Docker へ接続する

概要

Docker はネットワークを使わない方法も平文でのネットワーク通信も可能です。ここでは Docker を安全に使うため TLS を使用して信頼できるクライアントから信頼できるサーバへのみ接続できるようにします。 Docker Engine の起動引数に認証局の証明書およびサーバの証明書と鍵を設定します。クライアントは認証局の証明書およびクライアントの証明書と鍵を設定して接続します。

環境

鍵の作成

証明書や鍵があれば別途作る必要はありません。証明書や鍵が無い場合にはこれらを作成します。認証局、Docker Engine(サーバ)、Docker クライアントの分をそれぞれ作成します。 作成されるファイル名は Docker Machine のデフォルト値で作成します。
作成中に様々な入力を求められますが、以下の 2 つ以外は何も入力しないでも大丈夫です。

Enter pass phrase for ca-key.pem:
Verifying - Enter pass phrase for ca-key.pem:

各コマンドの出力は参考のページなどでご確認下さい。

認証局用の作業

俗に言うオレオレ認証局(CA)の秘密鍵と公開鍵を作成します
$ openssl genrsa -aes256 -out ca-key.pem 4096
$ openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem

Docker Engine用の作業

サーバの鍵(server-key.pem)と証明書署名要求(server.csr)を作成します
$ openssl genrsa -out server-key.pem 4096
$ openssl req -sha256 -new -key server-key.pem -out server.csr

サーバの証明書(server.pem)を作成します
$ echo subjectAltName = IP:192.168.56.100,IP:127.0.0.1 > extfile.cnf
$ openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server.pem -extfile extfile.cnf

Docker クライアント用の作業

クライアントの鍵(key.pem)と証明書署名要求(client.csr)を作成
$ openssl genrsa -out key.pem 4096
$ openssl req -new -key key.pem -out client.csr

クライアントの証明書(cert.pem)を作成
$ echo extendedKeyUsage = clientAuth > extfile.cnf
$ openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf

署名と鍵の整理

証明書署名要求は不要なため削除
$ rm -v client.csr server.csr

秘密鍵は所持者のみが読めるようにします
$ chmod -v 0400 ca-key.pem server-key.pem key.pem

証明書は全てのユーザが読めるようにします
$ chmod -v 0444 ca.pem server.pem cert.pem

Docker Engine の設定

CAの証明書と、Docker Engine の証明書と鍵を使用するように--tlsverify --tlscacert=ca.pem --tlscert=server.pem --tlskey=server-key.pemを追加。
所持する全ての IP で tcp の 2376 番ポートでリッスンするように ExecStart に-H tcp://0.0.0.0:2376を追加
これらの設定を起動引数に設定します。
$ vim /usr/lib/systemd/system/docker.service

[Service]
# ExecStart=/usr/bin/dockerd
ExecStart=/usr/bin/dockerd --tlsverify --tlscacert=ca.pem --tlscert=server.pem --tlskey=server-key.pem -H tcp://0.0.0.0:2376

設定を反映し docker を再起動します
$ systemctl daemon-reload
$ systemctl restart docker

TCP の 2376 で動いていることを確認
$ netstat -tln | grep 2376

tcp6       0      0 :::2376                 :::*                    LISTEN

Docker クライアント

作成した証明書と鍵を配置して、TLS を使用する設定をして Docker Engine へ接続します。

証明書と鍵の配置

ホームディレクトリに .docker ディレクトリを作成し、このディレクトリに認証局の公開鍵(ca.pem)とクライアントの証明書(cert.pem)と鍵(key.pem)をコピーします。

$ dir /b

ca.pem
cert.pem
key.pem

このディレクトリは DOCKER_CERT_PATH 環境変数でも変更できます。
$ export DOCKER_CERT_PATH=~/.docker/dev/

実行時に TLS を使うことを指定する

実行時に --tlsverify を指定します。
$ docker -H tcp://192.168.56.100:2376 --tlsverify run hello-world

Hello from Docker!
(略)

環境変数TLS を使うことを指定する方法

TLS の使用は DOCKER_HOST 環境変数で指定します。
set DOCKER_TLS_VERIFY=1

環境変数で指定した場合には実行時に --tlsverify 指定する必要はありません。
$ docker -H tcp://192.168.56.100:2376 run hello-world

Hello from Docker!
(略)

ダメな例

証明書や鍵をディレクトリに置いていない(読めない)と以下のエラーが発生します。

Could not read CA certificate "C:\\Users\\user\\.docker\\ca.pem": open C:\Users\user\.docker\ca.pem: The system cannot find the file specified.

環境変数でも実行時にも指定してない場合は以下のエラーが発生します。

Get http://192.168.56.100:2376/v1.24/containers/json: malformed HTTP response "\x15\x03\x01\x00\x02\x02".
* Are you trying to connect to a TLS-enabled daemon without TLS?

参考: docs.docker.com

Windows から Virtualbox 上の docker ホストへ接続する

概要

Windows 8.1 で docker を使用するには、Virtualbox を使用しないといけません。Docker ホストは docker-engine をインストールした段階ではリモートから接続できません。今回はリモートから TCP の 2375 番ポートで接続できるように Docker ホストを設定します。また、設定できたことを確認するため Docker クライアントからの接続も試みます。

環境

Docker ホストの設定

リモートにいる Docker クライアントから接続できるように設定します。クライアントから接続するためのポートと IP を確認します。Docker ホストが持つ全ての IP の 2375 ポートで接続できるようにします。

設定ファイルの場所を確認
$ rpm -ql docker-engine | grep docker.service$

/usr/lib/systemd/system/docker.service

所持する全ての IP で tcp の 2375 番ポートでリッスンするように ExecStart に-H tcp://0.0.0.0:2375を追加
$ vim /usr/lib/systemd/system/docker.service

[Service]
# ExecStart=/usr/bin/dockerd
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375

設定の反映と docker の再起動
$ systemctl daemon-reload
$ systemctl restart docker

TCP の 2375 で動いていることを確認
$ netstat -tln | grep 2375

tcp6       0      0 :::2375                 :::*                    LISTEN

ホストオンリーアダプタ(今回は enp0s8 )の IP を確認
$ ifconfig | grep -A 1 enp

enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.2.15  netmask 255.255.255.0  broadcast 10.0.2.255
--
enp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.56.100  netmask 255.255.255.0  broadcast 192.168.56.255

※注意:ファイアーウォールの設定

Windows からのリクエストを受付けるため Docker ホストとなる OS のファイアーウォールで TCP の 2375 ポートを通すように設定しないといけません。今回は試すだけなのでファイアーウォールを停止します。ちゃんと使う場合はキチンと設定しましょう。 Oracle Linux 7 からはファイアーウォールに iptables ではなく firewalld を使用しています。

ファイアーウォールを停止して起動しないようする
systemctl stop firewalld
systemctl disable firewalld

Docker クライアントの設定

Docker クライアントは Docker ホストが待ち受けている IP とポートへ接続します。クライアントは接続したい Docker ホストを指定します。Docker ホストの指定は実行時に指定する方法と環境変数で指定する方法があります。

実行時に Docker ホストを指定する方法

実行時に -H オプションを付けてその後に待ち受けている IP とポートを指定します。
$ docker -H tcp://192.168.56.100:2375 run hello-world

Hello from Docker!
(略)

環境変数で Docker ホストを指定する方法

Docker ホストの指定は DOCKER_HOST 環境変数で指定します。
set DOCKER_HOST=tcp://192.168.56.100:2375

環境変数で指定した場合には実行時に指定する必要はありません。
$ docker run hello-world

Hello from Docker!
(略)