参考資料:Linux研修【ハンズオン】コンテナを体験してみよう!/仮想マシン・コンテナの概念と利用

2021年3月26日開催のLinuCレベル1ハンズオンセミナーの参考資料になります。技術解説セミナーでは初めての「ハンズオン形式」にて開催します。Dockerコンテナの操作を学んで最後にはWordPressサーバーの構築まで体験していただきます。本体験を通じて「1.01.2:仮想マシン・コンテナの概念と利用」の理解を深めていただければ幸いです。

KatacodaのCentOS PlaygroundでDockerを使う

はじめに、KatacodaのCentOS Playgroundを使用します。以下のサイトにアクセスして「Playground」の「Explore Playground」をクリックしてください。

https://www.katacoda.com/courses/centos/

「Welcome!」画面が表示されたら、「START SCENARIO」ボタンをクリックしてシナリオを開始します。(実際はシナリオはありません)

左側に「Hello World」が表示されますが、「CONTINUE」ボタンはクリックしないでください。クリックするとシナリオが終了してしまいます。

「Hello World」表示が邪魔な場合は、右のコンソール画面との境目をクリックしたまま左にドラッグすると縮小されます。最も縮小された場合はStepsという表示のみになります。

右上角にある設定アイコンをクリックするとテキスト表示が拡大されたプレゼンモードになります。

CentOSプレイグラウンドの状態確認Ÿ

システム情報を表示

uname
uname –a
uname -r

catコマンドでLinux OSのバージョンを表示

cat /etc/os-release
cat /etc/centos-release

ホスト名設定コマンドでカーネル情報を確認

hostnamectl

hostnamectlはサブコマンドなしに実行するとホスト名と関連情報を表示できます。 Virtualizationの項目がkvmになっているはずです。KVMはLinuxの代表的な仮想化ソリューションです。このインスタンスが仮想で動作していることが確認できます。

サーバアプリケーションのインストール

コンテナ技術を使ったWebサーバーの構築の前に、LinuxマシンでのWebサーバー構築を体験していただきます。Webサーバーアプリケーションは著名なApache HTTPサーバーを使用します。

CentOSではApache2.4が採用されています。yumコマンドでパッケージ情報を確認後、インストールしてsystemctlコマンドで起動を行います。

Apache(httpd)のインストールと起動

yum info httpd
yum install httpd -y
systemctl start httpd

続けてsystemctlコマンド、psコマンド、pstreeコマンドでApacheの動作確認もしてみましょう。

systemctl status httpd
ps aux | grep httpd
pstree

起動が確認できたらWebプレビューで80番ポートにアクセスしてApacheのテストページが動作していることを確認しましょう。

Document Rootにindex.hmlファイルを配置し表示

Apache Webサーバーが公開するディレクトリの最上位ディレクトリつまりDocument Rootは「/var/www/html」です。ここにindex.htmlファイルを配置して、テストページと異なるページを表示してみましょう。

echoコマンドで/var/www/htmlに単純なindex.htmlを作成します。

echo Apache Works! > /var/www/html/index.html

ファイルが作成できたかどうか、念のためcatコマンドで確認してみましょう。

cat /var/www/html/index.html

Apacheインストール後に表示したWeb Previewのウインドウを再読み込みして、作成したindex.htmlファイルの内容が表示されるかを確認しましょう。

ここまでが一般的なWebサーバーの構築になります。psコマンドやpstreeコマンドでサーバーで実行されているプロセスを確認しましたが、Webサーバーのプロセスを含むたくさんのプロセスが実行されていました。

この後、コンテナによるWebサーバー構築を体験していただきますので、その違いを実感していただければと思います。

Dockerでコンテナを動かす

CentOS PlagroundにはあらかじめDockerは導入済みです。まずはバージョンを確認しましょう。バージョン確認のためのコマンドは複数あります。最もシンプルなのが-v、最も詳細なのがinfoです。

Dockerのバージョン確認

docker -v
docker version
docker info

­ちなみに、バージョンが1.2.xの場合は新体系コマンドは使えない古いバージョンですのでアップデートしましょう。
1.3xの場合でもビルドのバージョンが古いのでアップデートしましょう。
なお、まれにバージョンが19.xx.xのインスタンスに当たることがありますが、その場合はアップデートの必要はありませんので、次のステップに進むまで少しお待ちください。

yum update docker -y

Dockerの再起動と起動確認

インストールが完了したら、systemctlコマンドでDockerを再起動して、起動確認も行います。続けて、docker -vコマンドでアップデート後の情報を確認しましょう。バージョンが19.xx.xの人は何もしなくて結構です。

systemctl restart docker
­systemctl status docker
docker -v

Dockerヘルプの使い方

Dcokerは非常にたくさんのコマンドが用意されています。全てを覚えるのは並大抵ではありませんので、ヘルプコマンドを活用しましょう。

docker help
docker container --help
docker container run --help

第一階層のヘルプはハイフン無し。第二階層以降はハイフン2つ(–)を付けてhelpを入力します。新体系でも旧体系でもちゃんと表示されます。

Hello Worldコンテナの実行

最もポピュラーな動作確認用のコンテナを実行してみましょう。旧体系の場合は、

docker run hello-world

新体系の場合は、

docker container run hello-world

です。以降、ハンズオンでは基本的に旧体系のコマンドを使用します。同じ動作をするのにcontainerと余計に入力しなくてはいけないって時間の無駄ですよね。

UbuntuコンテナをデプロイしてDockerの基本操作を学ぶ

ここからは本格的にコンテナを動かしていきます。

コンテナの実行(run=pull+create+start)

docker runコマンドでubuntu18.04(bionic beaver)のコンテナをubu1という名前で実行しbashを起動します。

­docker run -it --name ubu1 ubuntu:bionic /bin/bash

オプションは、-iが–interactiveの略でキーボードからの入力を標準入力としてシェルに伝える、-tが–ttyの略でシェルのプロンプト表示を有効にするという意味です。-i -tと分けても良いのですが-itとまとめた方が楽です。

ちなみに、コンテナイメージを指定する際、ubuntuの後にセミコロン(:)を付け、取得したいイメージのバージョンを指定しています。

コンテナが起動できたらコンソールがCentOSのものからUbuntuのものに変わっているはずです。

Ubuntuのバージョン確認

catコマンドでubuntuのバージョンを確認し、unameコマンドでCentOSのカーネルを共有していることを確認します。

cat /etc/os-release
cat /etc/lsb-release
uname -r

確認後、exitしておきましょう。コンソールが再びCentOSのものに戻りました。

コンテナの起動と停止(start,stop)

以下の一連のコマンドを実行し、コンテナの状態を確認しましょう。

docker ps
docker ps -a
docker start ubu1
docker ps
docker stop ubu1
docker ps

Ubuntuコンテナをバックグラウンドで実行

docker runコマンドでubuntu18.04(bionic beaver)のコンテナをubu2という名前で-dオプションを追加してバックグラウンドで実行します。2度目なので起動が速いはずです。

docker run -dit --name ubu2 ubuntu:bionic /bin/bash

当然コンソールはCentOSのものです。念のためdocker psでバックグラウンドが実行されているのを確認しましょう。

docker ps

次にバックグラウンドで動いているubu2コンテナにdocker execコマンドでcatコマンドを指定しOS情報を取得します。

docker exec ubu2 cat /etc/os-release

コンソールがCentOSのままであることも確認しましょう。

Ubuntuコンテナにアタッチ

バックグラウンドで実行中のubu2コンテナにアタッチします。

docker attach ubu2

コンソールがubuntuのものに変化しているはずです。確認後、exitしておきます。

ログの確認

logsコマンドでコンテナを指定するとコンテナ毎にログを確認できます。

docker logs ubu1
docker logs ubu2

ubu1とubu2の違いを確認しましょう。

コンテナの管理

psコマンドで停止しているコンテナ一覧を取得し、rmコマンドで任意のコンテナを削除します。

docker ps -a
docker rm

container pruneコマンドなら停止中のコンテナをまとめて削除可能です。

docker container prune

イメージの管理

imagesコマンドでイメージの一覧を取得できます。rmiコマンドでイメージの削除ができます。idを指定してhello-worldのコンテナを削除しましょう。この後使うので、ubuntuのイメージだけは残していてください。

docker images
docker rmi

Docker Hubの公式Apacheコンテナを複数動かす

名前を付け、ポートを指定してバックグランドで実行

docker run -d --name apa01 -p 8081:80 httpd
docker run -d --name apa02 -p 8082:80 httpd 

2つめは1つめで取得したローカルイメージを使用しているのでコンテナ実行が速いです。

Webプレビューでそれぞれのポートを指定して動作確認

双方「It Works!」と表示されているはずです。

­docker psでコンテナの状態を確認

ホストOSにインストールしたApacheとあわせて3つが同時に動いていることを確認しましょう。

ホストOSへのインストールの場合、Apache Webサーバーが一つしか動かせませんが、コンテナを使うことで複数のWebサーバーを同時に互いに影響し合わずに動かすことができるようになります。

隔離されているApacheコンテナのindex.htmlを変更する

index.htmlファイルを2つ作成

ディレクトリを2つ作成して、区別が付くようににindex.htmlファイルを作成します。

­mkdir web1 web2 && echo Web1 Works! > web1/index.html && echo Web2 Works! > web2/index.html

docker cpコマンドでコンテナ内の指定ディレクトリにindex.htmlを配置

docker cpコマンドを使えば隔離されているコンテナ内にファイルをコピーすることができます。

docker cpコマンドの後に、ホストOS側のファイルを指定し、続けてコピーしたいコンテナのディレクトリを指定します。

docker cp web1/index.html apa01:/usr/local/apache2/htdocs/ 
docker cp web2/index.html apa02:/usr/local/apache2/htdocs/

­Webプレビューでそれぞれのポートを指定して動作確認

8081番の方が「Web1 Works!」、8082番が「Web2 Works!」が表示されていればOK。

隔離されているコンテナにホストOS側からファイルをコピーできることが確認できました。

コンテナのデタッチの動作確認

Linux実機や仮想マシンに導入したDockerはキーボードのショートカット(Ctrl+pのあとにCtrl+q)でコンテナをデタッチできますが、KatacodaのLinux環境でそれを実行するとPlayground(インスタンス)が使えなくなります。

再度ubuntuコンテナを実行して試してみましょう。

docker run -it --name ubu3 ubuntu:bionic /bin/bash

Ctrl+pのあとにCtrl+qを入力すると、赤い文字で「The environment has expired.Please refresh to get a new environment.」と表示され、CentOS Playgroundが使えなくなります。

当日のセミナーではここでLinux実機のコンソールに切り換えて、ショートカットによるコンテナのデタッチをお見せします。

KatacodaのUbuntu PlaygroundでDockerを使う

今度は、KatacodaのUbuntu Playgroundを使用します。以下にアクセスして「Ubuntu 20.04 Playground」の「Start Scenario」をクリックしてください。

https://www.katacoda.com/courses/ubuntu

画面左の「Hello World」表示が邪魔な場合は、右のコンソール画面との境目をクリックしたまま左にドラッグすると縮小されます。最も縮小された場合はStepsという表示のみになります。

右上角にある設定アイコンをクリックするとテキスト表示が拡大されたプレゼンモードになります。

Ubuntu 20.04 Playgroundの状態確認

システム情報を表示

uname -a
uname -r

catコマンドでLinux OSのバージョンを表示

cat /etc/os-release

ホスト名設定コマンドでカーネル情報を確認

hostnamectl

プロンプトの変更

Ubuntu Playgroudのコンソールは$しか表示されず、わかりにくいのでシェル変数でコンソール情報を変更します。

export PS1="[\u@$HOSTNAME \w]$"

Ubuntu Playgroundの特徴(CentOS Playgroundとの違い)

docker psで起動中のコンテナが無いことを確認した上でdocker imagesを実行してみましょう。

docker ps
docker images

Dockerイメージが多数表示されますね。Ubuntuのインスタンスには、はじめからDockerイメージが多数含まれています。

また、メニューに「IDE」や「Visual Host」というボタンが用意されています。

IDEボタンを押してみましょう。ほどなくしてVS Codeが起動します。
Visual Hostボタンを押しましょう。今度はWeave Scopeが起動します。

Ubuntuのインスタンスには、このような特別な機能が統合されています。

Dockerの動作確認

dockerのバージョンも確認しておきましょう。

docker -v
docker version

再びpsコマンドを実行してみましょう。

docker ps -a

先ほど起動したVisualize Host[=Weave Scope]のコンテナが動いているのが確認できます。

CentOSのコンテナを動かす

今度はUbuntu Playgroundの上でCentOSのコンテナを動かしてみましょう。

docker runコマンドでCentOSのコンテナをcent7testという名前で実行しbashを起動します。centos:7でバージョン指定しています。centosのみだと最新のバージョン(いわゆるlatest、現時点でCentOS8)が取得されます。

docker run -it --name cent7test centos:7 /bin/bash

catコマンドでOSのバージョンを確認し、unameコマンドでubuntuのカーネルが共有されていることを確認しましょう。

cat /etc/os-release
uname -r

確認後、exitしておきましょう。

Dockerfileでカスタムコンテナイメージを作成する

Dockerfileは、カスタマイズしたコンテナイメージを作成するための手順書のようなものです。

Dockerfileを使って、index.htmlを置き換え済みのApacheコンテナイメージを作成してみましょう。

index.htmlファイルを用意

Apache Web Server build by Dockerfileと記載されたindex.htmlファイルを作成します。

­echo Apache Web Server build by Dockerfile > index.html

念のためcatコマンドで内容を確認しておきましょう。

cat index.html

Dockerfileを作成

以下の内容をcatコマンドのヒアドキュメントでDockerfileとして作成します。httpdのイメージを取得してindex.htmlファイルをDucument Rootにコピーするように指示しているだけのシンプルな内容です。

­FROM httpd 
COPY index.html /usr/local/apache2/htdocs/

以下のコードはコピペはせず、全て手打ちしてください。2行目以降の大なり記号は改行すると表示されます。Dockerfileの一文字目は大文字です。index.htmlと/usr…の間は半角スペースが入ります。

­cat > Dockerfile << EOF
> FROM httpd
> COPY index.html /usr/local/apache2/htdocs/
> EOF

EOFを入力後エンターキーでコンソールが帰ってきます。

念のためcatコマンドでDockerfileの内容を確認します。間違いがあった場合はviエディタまたはVScodeで修正しましょう。

cat Dockerfile

index.htmlを置き換え済みのApacheコンテナイメージを作成

Dockerfileを使ってイメージを作成するには以下のコマンドを使用します。

docker build –t [イメージ名] [Dockerfileがあるディレクトリ]

今回はapaimgという名前で新しいApacheコンテナイメージを作成します。Dockerfileがあるディレクトリはカレントディレクトリです。

docker build -t apaimg .

実行中のログを見ると何が行われているかわかるはずです。正常に終了すれば最後の2行にSuccessfully〜というログが表示されます。

docker imagesコマンドで作成したイメージがあるか確認しましょう。

docker images

apaimgとhttpdという名前のイメージがあるはずです。取得したhttpdコンテナイメージをカスタマイズしたapaimgコンテナイメージが作成されたと言うことです。

作成したイメージで新たなApacheコンテナを実行

オプション-dを付けて、ポートを80番同士で繋ぎ、apa03という名前でバックグラウンドで実行します。詳細説明は省きますが、Apacheコンテナはその仕様上、バックグラウンドで実行する必要があります。-itなどで実行するとすぐにコンテナが停止してしまいますので注意してください。(時間があるときに色々と試してみてください。)

docker run -d --name apa03 -p 80:80 apaimg

Web Previewで「Apache Web Server build by Dockerfile」と表示されているはずです。

ここまで、Dockerfileを使ってカスタマイズしたコンテナイメージを使ったWebサーバー構築ができました。

Docker ComposeでWordPressサイトを構築する

一般的に、WordPressサイトの構築には、 LAMP環境と呼ばれる、Linux OSApacheMySQL(またはMariaDB)PHP(またはPython)の4つが必要です。

LinuxサーバーでWordPressを使うには、 LAMP環境が連携するように設定しなくてはいけません。

Docker HubにはWordPress社公式のコンテナが公開されており、Docker Composeを使えば、LAMP環境の連携を設定した上でWordPressサイトが簡単に構築できます。

複数のコンテナで構成されるアプリケーションの構築に必要な、コンテナイメージの情報や起動のための各種設定、さらにコンテナ同士が連携するために必要な手順などをdocker-compose.ymlファイルに記載してdocker-composeコマンドで実行します。構築に必要なコマンドは1つだけです。

Docker Composeのインストール

Ubuntu Playgroundでは導入済みです。

もしも、CentOS Playgroundで試したい場合はyum install docker-composeでインストール できます。

Docker Composeのバージョン確認

docker-compose -v

プロジェクト用ディレクトリを作成し同ディレクトリに移動

mkdir mywp && cd mywp

docker-compose.ymlの作成

以下のWordpress公式の設定をコピーし、viエディタを使いdocker-compose.ymlというファイル名で作成します。

version: '3.1'
services: wordpress: image: wordpress restart: always ports: - 8080:80 environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_USER: exampleuser WORDPRESS_DB_PASSWORD: examplepass WORDPRESS_DB_NAME: exampledb volumes: - wordpress:/var/www/html db: image: mysql:5.7 restart: always environment: MYSQL_DATABASE: exampledb MYSQL_USER: exampleuser MYSQL_PASSWORD: examplepass MYSQL_RANDOM_ROOT_PASSWORD: '1' volumes: - db:/var/lib/mysql
volumes: wordpress: db:

右上のコピーアイコンを押してパソコンのクリップボード経由でエディタなどにペースとしましょう。エディタはviコマンドでも良いし、IDEボタンを押してVSCodeで作成しても良いです。

ちなみに、apacheとphpはWordPressの公式イメージによって自動的に組み込まれます。

vi docker-compose.yml

念のためcatコマンドで内容を確認しておきましょう。

cat docker-compose.yml

Docker Composeを実行

docker-compose upコマンドを実行すると、docker-compose.ymlに記載された内容で、WordPressとMySQLのコンテナイメージが取得され、それぞれが連携するように自動的に設定が行われます。ちなみに、-dオプションはデタッチの意味でバックグラウンドで実行します。

docker-compose up -d

特にエラーが表示されていなければ導入は完了です。完了まで多少時間がかかる場合があります。

Docker Composeの基本コマンド

実行 ­docker-compose up (–d) 
停止 ­docker-compose stop
終了 ­docker-compose down(停止、コンテナやネットワークの削除。イメージは残る。)
­終了 docker-compose down --rmi all(イメージを含む全削除)

WordPressの動作チェック

ブラウザ左上の+ボタン(WebPreview)をクリックして「Select port to view on Host 1」を選択し、####に8080を入力してDisplay Portボタンをクリック。WordPressのロゴが入った初期設定画面が表示されたら成功です。

日本語を選択して続行すると「ようこそ」画面が表示されます。サイトのタイトルやユーザー名など、必須事項を記入してインストールボタンを押せば設定が完了します。

Katacodaのインスタンス自体、短時間で消滅してしまうので必須事項は適当な物で良いですが、ユーザー名やパスワードをadminやdockerなど、単純なものにするとWebブラウザが当該ユーザーのパスワードが漏洩しているとして警告してくることがありますのでご注意ください。

次の画面で、設定したアカウントでログインすればWordPressのダッシュボードが表示されます。

ダッシュボード左上のタイトルにマウスオーバーして「サイトを表示」をクリックすればブログ画面が表示されます。

WordPressの使い方についてはセミナー趣旨と異なるので、これ以上の解説は控えます。

Dockerコマンドでコンテナの動作確認

docker psコマンドでWordPressとMysqlのコンテナが動作していることを確認しましょう。

docker ps

余裕があったらpsコマンドやpstreeコマンドでUbuntu Playgroundで動作中のコンテナのプロセスについても確認してみましょう。

ps aux | grep '/run/docker'
pstree

動作中のコンテナIDと一致するプロセスが見つかるはずです。プロセスにはnamespace(名前空間)という単語が含まれており、それぞれが隔離されたプロセスとして実行されていることが見て取れます。

参考までに、docker image inspectコマンドでイメージの詳細が確認できます。詳細な説明はしませんが、phpやapacheに関する記述があるのが確認できるはずです。

docker image inspect wordpress

Visualise Host(Weave Scope)で確認

ついでに、「Visualise Host」ボタンを押して視覚的なコンテナ情報を確認しましょう。

Dockerfileで作成したイメージから実行したApacheコンテナとWordPressコンテナで実行されているプロセスを確認してみましょう。

Apacheコンテナではhttpdという名前のプロセスが、WordPressコンテナ内部ではapache2という名前のプロセスが動いており、相互が独立して動いています。

Docker Composeを実行しコンテナを停止して破棄する

docker-compose down

WordPressに関わる全てのコンテナが停止して破棄されます。

以上でセミナーのハンズオンパートは終了です。