Oracle Linux 7.1 の Docker コンテナに SSH で接続する

今回は、表題の通り、Oracle Linux 7.1 の Docker コンテナにSSHでアクセスするために必要な手順を紹介します。

前提として、VirtualBox 上の Oracle LinuxVagrant でゲストOSを構成し、そこに Docker コンテナを立てているものとします。今回は、この Docker コンテナにホストOS からSSHで接続します。

f:id:charlier_shoe:20151022120149p:plain

今回は、過去の記事で作成した環境をベースに作業を行いますので、前提条件の詳細については、左記の記事を参照ください。

手順

1. Vagrantfile の編集

1-1. ポートマッピング

Docker コンテナの22ポートにアクセスするため、ゲストOS <-> Docker コンテナ、およびホストOS <-> ゲストOSのポートマッピングを設定します。

ゲストOS <-> Docker コンテナ のポートマッピングは、”docker run" コマンドのオプションで指定します。Vagrant から Docker コンテナをプロビジョニングをしているので、Vagrantfile 内に run コマンドを記述しています。したがって、この記述にポートマッピングのオプションを追記します。

今回は、Docker コンテナの22番ポートをゲストOSの10022番ポートにマップします("-p 10022:22" という部分)。

Vagrant.configure(2) do |config|
…
    # Provisioner settings
    config.vm.provision "docker" do |d|
        d.build_image "/vagrant", args: "-t charlier_shoe/hoge"
        d.run "charlier_shoe/hoge",
               args: "-d -t -p 10022:22 -p 17001:7001 -v /vagrant:/tmp/shared --memory-swap -1"
    endend

ホストOS <-> ゲストOS のポートマッピングは、Vagrantfile 内のゲストOSの設定で行います。

以下の例では、ゲストOSの10022番ポートを、ホストOSの10022番ポートにマップしています。

Vagrant.configure(2) do |config|
…
    # VM settings
    config.vm.define :dock, primary: true do |dock|
        …
        dock.vm.network "forwarded_port", host: 10022, guest: 10022
    endend

以上の設定により、ゲストOSの22番ポートが、localhostの10022番ポートにマッピングされます。

以下、Vagrantfile の全体を示します。今後 Docker コンテナ上で WebLogic Server を動作させる予定なので、コンテナの7001番に対するポートマッピングの設定も記述しています。

Vagrant.configure(2) do |config|

    # VM settings
    config.vm.define :dock, primary: true do |dock|
        dock.vm.box = "oraclelinux-7.1-x86_64"
        dock.vm.provider "virtualbox" do |v|
            v.name = "dock"
            v.cpus = "2"
            v.memory = "4096"
        end
        dock.vm.network "forwarded_port", host: 10022, guest: 10022
        dock.vm.network "forwarded_port", host: 17001, guest: 17001
    end

    # Provisioner settings
    config.vm.provision "docker" do |d|
        d.build_image "/vagrant", args: "-t charlier_shoe/hoge"
        d.run "charlier_shoe/hoge",
               args: "-d -t -p 10022:22 -p 17001:7001 -v /vagrant:/tmp/shared --memory-swap -1"
    end
end

2. Dockerfile の編集

Dockerfile を編集して、コンテナのビルド時に、コンテナに対して必要な構成変更をおこなうようにします。
今回利用するコンテナの場合、以下の構成変更を行う必要があります。

  • root ユーザーのパスワードの変更
  • PAM認証の設定変更
  • SSH ホストキーの構成
  • 22番ポートの開放
  • "docker run" 実行時の、SSH デーモンの起動

2-1. root ユーザーのパスワードの設定

本記事では、root ユーザーで接続することにします。
今回利用するコンテナ(Oracle のオフィシャル)では、root ユーザーのパスワードがわからない(設定されていない?)ので、ここで所望のパスワードに変更しておきます。

Dockerfile に記述する内容は、以下のとおりです。

RUN echo 'root:root' | chpasswd

2-2. PAM認証の設定変更

この手順をやっておかないと、SSH 接続で認証が終わった直後に切断される現象が起きます。

Docker の公式サイトのガイドにしたがって、Dockerfile に以下の記述を追加します。

RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

/etc/pam.d/sshd ファイルを編集して、SSH デーモンに適用される PAM認証の設定に手を入れているようです。
ちなみに、/etc/ssh/sshd_config を編集して PAM認証を無効にする方法が紹介されている場合もありますが、Oracle Linux のような RedHat 系のディストリビューションでは、この方法はサポートされていないようです。

2-3. SSH ホストキーの構成

今回利用するコンテナは、そのままでは SSH のホストキーが配置されていないので、新たに作成する必要があります。

Dockerfile に記述する内容は、以下のとおりです。

RUN /usr/bin/ssh-keygen -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key -N ''
RUN /usr/bin/ssh-keygen -t ecdsa -b 256 -f /etc/ssh/ssh_host_ecdsa_key -N ''
RUN /usr/bin/ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ''

ssh-keygen コマンドで、所定のパスにキーを生成しています。
キーのアクセス権を絞っておかないと、SSH デーモンの起動時にエラーになるような気がしますが、今回は不要でした。

2-4. 22番ポートの開放

22番ポート(SSH の通信用のポート)を解放して、外部からのアクセスを受け付けるようにします。

Dockerfile に記述する内容は、以下のとおりです。

EXPOSE 22

2-5. "docker run" 実行時の、SSH デーモンの起動

コンテナの起動とともに SSH デーモンが起動するようにしておきます。

Dockerfile に記述する内容は、以下のとおりです。

CMD ["/usr/sbin/sshd", "-D"]

以上で Dockerfile の編集は完了です。以下に Dockerfile の全体を示します。

FROM oraclelinux:latest
MAINTAINER Oracle Linux Product Team <ol-ovm-info_ww@oracle.com>

RUN yum install -y openssh-server
RUN yum install -y openssh-clients

RUN echo 'root:root' | chpasswd
# RUN sed -i 's/#PermitRootLogin yes/PermitRootLogin without-password/' /etc/ssh/sshd_config
# RUN sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config

# edit PAM auth configuration
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

# generate SSH host key
RUN /usr/bin/ssh-keygen -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key -N ''
## For ECDSA keys, the -b flag determines the key length by selecting from one of
## three elliptic curve sizes: 256, 384 or 521 bits.
RUN /usr/bin/ssh-keygen -t ecdsa -b 256 -f /etc/ssh/ssh_host_ecdsa_key -N ''
## Ed25519 keys have a fixed length and the -b flag will be ignored.
RUN /usr/bin/ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ''

EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

3. Docker コンテナをプロビジョニングする

いよいよ Docker コンテナをプロビジョニングします。
Vagrantfile を配置したフォルダをカレントにして、以下のコマンドを実行してください。

(vagrant up が終わっている状態)
$ vagrant provision

続いて、SSH でコンテナに接続してみます。

$ ssh -p 10022 root@localhost

パスワードが聞かれるので、"root" と入力します。これでコンテナにアクセスできるはずです。