【Linux標準教科書】最初の壁である環境構築をDockerを使って乗り越えてみた

## 困ったこと

[Linux標準教科書](https://linuc.org/textbooks/linux/)を使ってLinuxの勉強を始めました。
しかし、第2章でいきなり壁にぶつかります。

それは、環境構築です。

## 前情報

### 使用しているマシン

- M1 MacBook Air
- Mac OS: Ventura 13.4.1

### 使用したいOS環境

- CentOS のバージョン 7.x系
    - 標準教科書では7.3を使用していますが、LPI-Japanが公式で出しているYouTube動画では7.9を使用している


## 仮想マシンか？コンテナか？

別環境を立ち上げるということは、仮想マシンかコンテナを使用するのだろうという予測はつきました。
今回の例ではどちらが適しているのかを調べてみました。

### 両者の違い

- 仮想マシン（VM）:
    - 物理ハードウェア上にホストOSを経由して、完全に独立したゲストOSを実行する
    - それぞれのVMは独自のOSを持ち、必要なライブラリやアプリケーションを含む完全なシステムイメージを持つ
    - この完全な隔離により、異なるOSを同じ物理ハードウェア上で実行することが可能になるが、その分、リソースの消費が大きくなり、起動時間が長くなるというデメリットがある

- コンテナ:
    - アプリケーションとその依存関係をコンテナイメージとしてパッケージ化し、1つのOSカーネル上で実行する
    - 各コンテナは他から隔離されているものの、VMよりも軽量で、必要なライブラリやアプリケーションのみを含むため、リソース消費が少なく、起動時間が短いというメリットがある
    - コンテナは、特に開発とデプロイメントのプロセスを簡素化し、アプリケーションのポータビリティを高めることに優れている

現在の実務に近く、自分のスキルアップに繋がるという意味で、気持ち的にはDockerを使用したい。
しかし、どうやらコンテナを使って環境構築するには自分が使用しているマシンのOSと構築したい環境のOSが一致（互換性？）している必要がありそうです。

ただし、Dockerを使って別OSが**使えないわけがない**（謎の自信）ので調べてみると

> Dockerなどのコンテナ技術を使用すると、macOS上で軽量なCentOS環境をコンテナとして実行できます。DockerはmacOS Ventura 13.4.1をサポートしており、ARMアーキテクチャのMacであっても、適切なCentOSイメージを使用すればコンテナ内でLinux環境を実行できます。

とのことだったので、これにチャレンジしてみます。

## 実装

### 環境

- Docker: Docker Desctop 4.12.0 (85629)
- CentOS: CentOS Linux release 7.9.2009 (AltArch)

### 環境の構築

**Docker imageのダウンロード**
```
$ docker pull centos:7
7: Pulling from library/centos
6717b8ec66cd: Pull complete
Digest: sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4
Status: Downloaded newer image for centos:7
docker.io/library/centos:7

$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
centos       7         c9a1fdca3387   24 months ago   301MB
```

これで手元にCentOSのDockerイメージを取得することができました。
続いて、これを起動します。

```
$ docker run -itd --name centos7 -h centos7 centos:7
26ec84f1aac5b8f07d28c3670aec365a7500c7271f8f9cc4828e04a8c029310d

$ docker ps
CONTAINER ID   IMAGE      COMMAND       CREATED          STATUS          PORTS     NAMES
26ec84f1aac5   centos:7   "/bin/bash"   15 seconds ago   Up 14 seconds             centos7
```

`STATUS`がUPになっており、起動していることが分かります。
続いて、起動した環境の中に入ります。

```
$  docker exec -it centos7 /bin/bash
[root@centos7 /]#
```
現在地が`centos7`のルートになりました。
念のため、現在の環境の詳細を確認します。

```
[root@centos7 /]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (AltArch)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (AltArch)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7:server"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
```

`NAME="CentOS Linux"`と記載されていることから、目標通りの環境を構築できたことが確認できました🎉
コンテナから抜け出して、dockerを停止させます。

```
[root@centos7 /]# exit

$ docker stop centos7
centos7

$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
```

起動中のコンテナに何も表示されていないことを確認することができました。
先程作成したコンテナを再び起動させます。

```
$ docker start centos7
centos7

$ docker exec -it centos7 /bin/bash
[root@centos7 /]#
```

### コマンドのオプションについて

今回使用した
```
$ docker run -itd --name centos7 -h centos7 centos:7
```
というコマンドのオプションについて説明します。

- -i (または --interactive)
    - コンテナの標準入力（STDIN）を開いた状態に保持します。
これにより、実行中のコンテナに対してインタラクティブな操作が可能になります。
例えば、コンテナ内のシェルにコマンドを入力して操作したい場合に有効です。

- -t (または --tty)
    - 疑似TTY（仮想端末）を割り当てます。
コンテナに対してターミナルのようなインターフェースを提供し、ユーザーがコンテナ内で実行されるアプリケーションやシェルとインタラクティブに対話できるようになります。
これはコマンドライン操作やテキストベースのインターフェースが必要なアプリケーションに特に有効です。

- -d (または --detach)
    - コンテナをバックグラウンドで実行します。
バックグラウンドでコンテナを実行することで、ターミナルを占有せずに他の作業を続けることができます。
サーバーなどの長時間実行が必要なアプリケーションを起動する際に便利です。

- --name
    - コンテナに名前を割り当てます。
コンテナにわかりやすい名前を割り当てることで、後からそのコンテナを識別しやすくなり、docker stop や docker logs などのコマンドを使用する際に便利です。
ランダムに生成されるコンテナIDを覚える必要がなくなります。

- -h (または --hostname)
    - コンテナのホスト名を設定します。
ネットワーク上でコンテナを特定のホスト名で識別できるようになり、コンテナ内部から見た際のシステムのホスト名もこの値になります。
これは、ネットワーク設定や複数のコンテナ間での相互作用を扱う際に有効で、特定のホスト名での動作を期待するアプリケーションのテストに便利です。

### 立ち上げたCentOSの中身を確認

今回立ち上げたCentOSはかなり軽量なものです。
例えば
```
[root@centos7 /]# less
bash: less: command not found
```
のように、lessコマンドさえ使用することができません。
今後教科書で学習を進める上で必要になり次第使用可能な状態にしていきます。
現在のディレクトリ構成はこちら
```
[root@centos7 /]# ls
anaconda-post.log  dev  home  lib64  mnt  proc  run   srv  tmp  var
bin                etc  lib   media  opt  root  sbin  sys  usr
```

## 参考

- [コンテナを使ったLinux学習環境の構築方法と使用方法](https://www.youtube.com/watch?v=G_r8qPNJxmA)
- [M1MacBookでCentOSを使えるようにする【DockerHubからCentOSイメージを取得】](https://qiita.com/Ryo-hey/items/ba99e001a7b3cfca0879)