最小構成の CentOS 8 に SSH 接続可能な Docker コンテナを作ってみる

(2020/09/25)
トラブルシュート部分を下記の記事に分離しました。
[SSH 接続可能な Docker コンテナを載せた VM に繋がらなくなった](https://qiita.com/Shiratsuki_Kurom/items/7ce212f7a66fa94addef)


# 概要

最近 Docker に少し興味を持っていたのだが、仕事で Docker に触れる機会が今のところないので、自分で勝手に勉強することにした。
Google 先生や世の先人たちは CentOS 7 あたりで構築する記事をたくさん紹介してくれるが、CentOS 8 がリリースされて少し（結構？）経つので、せっかくなら新しいものでということで、試行錯誤を承知の上で少し遊んでみる。[^1]
今回は、SSH 接続が可能なコンテナを作り、ホストからコンテナへの SSH アクセスができることをゴールにする。

[^1]: CentOS 8 では Podman という Docker 互換のシステムが標準装備されているようなので、敢えて Docker を使う必要はないのかもしれない。


# 環境
 - Windows10 Home (1909)　（ホスト）
 - VirtualBox 6.1.4
 - CentOS 8.1.1911　（ゲスト）
 - Docker 19.03.8
 - Docker Compose 1.25.4


# 手順

## VM 起動

デフォルトでインストールすれば色々簡単かもしれないが、とりあえず Minimal（最小構成）でどこまで構築できるか試してみることにした。
CentOS 8 ではフルサイズのイメージを使用し、インストール中に構成を選択する箇所が出てくるのでそこで最小構成を選択。
VirtualBox での構築手順は省略。下記記事などを参考にした。

参考：[Virtualbox環境にて、CentOS8を構築する](https://qiita.com/taro-hida/items/fa05da9c7541bd825981)
参考：[初見でCentOS8](https://access-jp.co.jp/blogs/development/455)


## SSH 接続関連設定

OS がインストールできたら、ホスト側の TeraTerm から SSH 接続可能なところまで持っていく。

まずは VirtualBox 側でポートフォワーディングの設定。
SSH アクセスができればよいのだが、下記のようなイメージで、接続時に2222番ポートを指定すればゲスト VM へ、22222番ポートを指定すればコンテナへアクセスできるようにしたい。

ホスト ーーーー ゲスト ーーーー コンテナ
2222　ーーーー　22
22222 ーーーー　2222　ーーーー　22

そこで、VirtualBox では2222番と22番、22222番と2222番を対応付ける設定を行う。
なお、ゲスト VM の2222番とコンテナの22番の対応付けは、後の Docker 関連の設定にて実施する。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601682/f0e0c91c-9268-6e60-e712-7a190f879507.png)


ゲスト VM 側の設定に移る。
まずは SSH 接続を許可するようファイアウォールを設定。

```
# firewall-cmd --add-service=ssh --permanent
# firewall-cmd --reload
```

ネットワークインターフェースを有効化。

```
# nmcli connection up enp0s3
# nmcli connection modify enp0s3 connection.autoconnect yes
# nmcli connection show enp0s3
```

SELinux を無効化し、再起動。

```
# vi /etc/selinux/config
SELINUX=disabled
# reboot
```

これで、ホスト側の TeraTerm からゲスト VM に SSH 接続が可能になった。
接続の際はホスト名にIPアドレスを指定（当方環境では192.168.11.4）し、ポートは Virtual Box にてポートフォワーディング設定した通りに指定（今回は2222）すればOK。


## Docker 導入

<font color="LightGray">~~今回はオフライン環境に構築することを前提としてやってみる。~~</font>
途中まではオフライン環境で構築することを考えていたが、後段の Docker コンテナ起動のところでどうしても外部通信が必要になるので、結局はオンライン環境での作業になってしまった。
そのため、途中まではオフライン向けの無駄な手順を踏んでいるがご容赦を。
（全てオンラインでの手順に書き直すかも）

なお、オフラインでの導入手順は下記記事が参考になった。

参考：[docker環境構築 〜オフライン環境で使用するにはどうすれば良いかを考える〜](https://qiita.com/kod314/items/e574ac12c23598e0d903)


まず必要資材をホスト側にダウンロード。

Docker 19.03.8
https://download.docker.com/linux/static/stable/x86_64/docker-19.03.8.tgz
Docker Compose 1.25.4
https://github.com/docker/compose/releases/download/1.25.4/docker-compose-Linux-x86_64

WinSCP などでゲスト VM に資材を送り込み、下記のコマンドで展開。

```
$ tar zxvf docker-19.03.8.tgz
-bash: tar: コマンドが見つかりません
```

……なるほど、最小構成インストールだと`tar`コマンドが無いと。
`tar`が入っていないのはどうなのかと思いつつ、コマンドを導入し、リトライ。

参考：[CentOS8 (Minimum) インストールしてとんでもなかったこと一覧](https://north.thco.mp/2019/09/26/centos8-minimum/)

```
$ sudo yum install tar
$ tar zxvf docker-19.03.8.tgz
```

Docker Compose はダウンロード資材自体が実行ファイルなので、リネームして所定の位置に置き、実行可能にしてやればよい。

```
$ sudo mv docker-compose-Linux-x86_64 /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
```

この先、いちいち`sudo`をつけて`docker`コマンドを打つのは面倒なので、権限付与。

```
$ sudo usermod -aG docker $USER
```


## コンテナ起動

コンテナで`ssh`を動かすため、`Dockerfile`と`docker-compose.yml`をゲスト VM のホームディレクトリに作成。
コンテナのイメージファイルには、軽量 OS の Alpine Linux を用いる。
なお、コンテナで`ssh`を常駐させる方法は下記記事を参考にした。

参考：[Dockerコンテナでsystemd無しのSSH](https://qiita.com/kkk627/items/b7cc990f310f04a584c7)

``` :Dockerfile
FROM alpine

# ssh ほか導入
RUN set -x && apk update && apk upgrade \
  && apk add --no-cache openssh openrc \
  && apk add --no-cache bash \
  && apk add --update busybox-suid
RUN rc-update add sshd && rc-status
RUN mkdir -p /run/openrc/ && touch /run/openrc/softlevel

# sshd 設定
RUN sed -i 's/^AllowTcpForwarding no/AllowTcpForwarding yes/g' /etc/ssh/sshd_config
RUN sed -i 's/^#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config

# 一般ユーザ作成
RUN adduser -D test

# パスワード設定
RUN echo 'root:root' | chpasswd
RUN echo "test:test" | chpasswd

# ログイン時のバナーを非表示
RUN echo "" > /etc/motd

# sshd を起動し、そのままの状態にする
CMD /etc/init.d/sshd start && tail -f /dev/null
```

``` docker-compose.yml
version: '3.8'

services:
  test:
    build: .
    container_name: test
    hostname: test
    ports:
      - "2222:22" # ゲストVMとコンテナのポートを対応付ける設定
    tty: true
```

上記ファイルを作成したら、いよいよコンテナを起動。

```
[centos@dockertest ~]$ docker-compose build
[centos@dockertest ~]$ docker-compose up -d
```

コンテナが立ち上がったら、ホストから SSH でコンテナにアクセスしてみる。

```
test:~$
```

以上で、SSH アクセス可能な Docker コンテナを作ることができた……と思っていた。

（[問題発生編](https://qiita.com/Shiratsuki_Kurom/items/7ce212f7a66fa94addef) に続く）

# まとめ

手探りながら、とりあえず SSH 接続可能な Docker コンテナを動かすことができた。
それにしても、Minimal の CentOS 8 には`tar`が入らないことにびっくり。どういう経緯で不要と判断されたのだろうか……。