この記事は、クラウドでのコンテナー化されたワークロードのデプロイと管理に関するウェビナーシリーズを補足するものです。 このシリーズでは、コンテナーのライフサイクル管理、マルチコンテナーアプリケーションのデプロイ、ワークロードのスケーリング、Kubernetesの理解など、コンテナーの基本事項を取り上げ、ステートフルアプリケーションを実行するためのベストプラクティスを強調しています。

このチュートリアルには、シリーズの最初のセッションであるコンテナ入門で取り上げた概念とコマンドが含まれています。

序章

Dockerは、コンテナー化されたアプリケーションをデプロイおよび管理するためのプラットフォームです。 コンテナーは、その柔軟性により、開発者、管理者、およびDevOpsエンジニアの間で人気があります。

Dockerには3つの重要なコンポーネントがあります。

  • Dockerエンジン
  • Dockerツール
  • Dockerレジストリ

Docker Engineは、コンテナーを管理するコア機能を提供します。 基盤となるLinuxオペレーティングシステムとインターフェイスして、コンテナーのライフサイクルを処理するための単純なAPIを公開します。

Docker Toolsは、DockerEngineによって公開されたAPIと通信するコマンドラインツールのセットです。 これらは、コンテナーの実行、新しいイメージの作成、ストレージとネットワークの構成、およびコンテナーのライフサイクルに影響を与えるさらに多くの操作の実行に使用されます。

Dockerレジストリは、コンテナイメージが保存される場所です。 各画像には、一意のタグで識別される複数のバージョンを含めることができます。 ユーザーはレジストリから既存のイメージをプルし、それに新しいイメージをプッシュします。 Docker Hub は、 Docker、Inc.によって管理されるホスト型レジストリです。独自の環境内でレジストリを実行して、イメージをエンジンに近づけることもできます。

このチュートリアルの終わりまでに、DockerをDigitalOcean Dropletにインストールし、コンテナーを管理し、イメージを操作し、永続性を追加し、プライベートレジストリを設定します。

前提条件

このチュートリアルに従うには、次のものが必要です。

デフォルトでは、dockerコマンドにはroot権限が必要です。 ただし、 docker グループのユーザーとしてdockerを実行することにより、sudoプレフィックスなしでコマンドを実行できます。

ドロップレットをこのように構成するには、コマンドsudo usermod -aG docker ${USER}を実行します。 これにより、現在のユーザーがdockerグループに追加されます。 次に、コマンドsu - ${USER}を実行して、新しいグループメンバーシップを適用します。

このチュートリアルでは、サーバーがsudoプレフィックスなしでdockerコマンドを実行するように構成されていることを前提としています。

ステップ1—Dockerをインストールする

ドロップレットにSSHで接続した後、次のコマンドを実行して、すでにインストールされている可能性のある既存のDocker関連パッケージを削除し、公式リポジトリからDockerをインストールします。

  1. sudo apt-get remove docker docker-engine docker.io
  2. sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
  3. curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  4. sudo apt-key fingerprint 0EBFCD88
  5. sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
  6. sudo apt-get update
  7. sudo apt-get install -y docker-ce

Dockerをインストールした後、次のコマンドを使用してインストールを確認します。

  1. docker info

上記のコマンドは、環境にデプロイされたDockerEngineの詳細を示しています。 次のコマンドは、Dockerツールが正しくインストールおよび構成されていることを確認します。 DockerEngineとToolsの両方のバージョンを出力する必要があります。

  1. docker version

##ステップ2—コンテナの起動

Dockerコンテナーは、レジストリーに保管されている既存のイメージから起動されます。 Dockerのイメージは、プライベートリポジトリまたはパブリックリポジトリに保存できます。 プライベートリポジトリでは、ユーザーはイメージをプルする前に認証する必要があります。 公開画像には誰でもアクセスできます。

hello-worldという名前の画像を検索するには、次のコマンドを実行します。

  1. docker search hello-world

hello-worldという名前に一致する画像が複数ある可能性があります。 画像の人気を示す星が最も多いものを選択してください。

次のコマンドを使用して、ローカル環境で使用可能なイメージを確認します。

  1. docker images

まだコンテナを立ち上げていないので、画像はありません。 これで、イメージをダウンロードしてローカルで実行できます。

  1. docker pull hello-world
  2. docker run hello-world

イメージをプルせずにdocker runコマンドを実行すると、DockerEngineは最初にイメージをプルしてから実行します。 docker imagesコマンドを再度実行すると、hello-worldイメージがローカルで使用可能になっていることがわかります。

より意味のあるコンテナであるApacheWebサーバーを起動してみましょう。

  1. docker run -p 80:80 --name web -d httpd

docker runコマンドに渡される追加のオプションに気付くかもしれません。 これらのスイッチの説明は次のとおりです。

  • -p —これはDockerEngineにホストのポート80でコンテナーのポート80を公開するように指示します。 Apacheはポート80でリッスンするため、ホストポートで公開する必要があります。
  • --name —このスイッチは、実行中のコンテナーに名前を割り当てます。 これを省略すると、DockerEngineはランダムな名前を割り当てます。
  • -d —このオプションは、コンテナーをデタッチモードで実行するようにDockerEngineに指示します。 これがないと、コンテナはフォアグラウンドで起動され、シェルへのアクセスがブロックされます。 コンテナをバックグラウンドにプッシュすることで、コンテナがまだ実行されている間もシェルを使用し続けることができます。

コンテナが実際にバックグラウンドで実行されていることを確認するには、次のコマンドを試してください。

  1. docker ps

出力は、webという名前のコンテナーが、ホストポート80にマップされたポート80で実行されていることを示しています。

次に、Webサーバーにアクセスします。

  1. curl localhost

次のコマンドを使用して、実行中のコンテナを停止して削除しましょう。

  1. docker stop web
  2. docker rm web

docker psを再度実行すると、コンテナーが終了していることが確認されます。

ステップ3—コンテナへのストレージの追加

コンテナは一時的なものです。つまり、コンテナが終了すると、コンテナ内に格納されているものはすべて失われます。 コンテナの存続期間を超えてデータを永続化するには、ボリュームをコンテナにアタッチする必要があります。 ボリュームは、ホストファイルシステムのディレクトリです。

ホスト上に新しいディレクトリを作成することから始めます。

  1. mkdir htdocs

次に、新しいスイッチを使用してコンテナを起動し、htdocsディレクトリをマウントして、ApacheWebサーバーのドキュメントルートをポイントします。

  1. docker run -p 80:80 --name web -d -v $PWD/htdocs:/usr/local/apache2/htdocs httpd

-vスイッチは、コンテナ内のhtdocsディレクトリをホストのファイルシステムにポイントします。 このディレクトリに加えられた変更は、両方の場所に表示されます。

次のコマンドを実行して、コンテナからディレクトリにアクセスします。

  1. docker exec -it web /bin/bash

このコマンドは、インタラクティブモードでターミナルをコンテナのシェルに接続します。 これで、コンテナ内にドロップされたことがわかります。

htdocsフォルダーに移動し、単純なHTMLファイルを作成します。 最後に、シェルを終了してホストに戻ります。

  1. cd /usr/local/apache2/htdocs
  2. echo '<h1>Hello World from Container</h1>' > index.html
  3. exit

curl localhostコマンドを再度実行すると、Webサーバーが作成したページを返していることがわかります。

ホストからこのファイルにアクセスできるだけでなく、次のように変更することもできます。

  1. cd htdocs
  2. cat index.html
  3. echo '<h1>Hello World from Host</h1>' | sudo tee index.html >/dev/null

curl localhostを再度実行すると、Webサーバーがホストから作成された最新のページを提供していることが確認されます。

次のコマンドでコンテナを終了します。 (-fは、Dockerを最初に停止せずに強制的に終了させます。)

  1. docker rm -f web

ステップ4—画像の作成

レジストリから既存のイメージを実行する以外に、独自のイメージを作成してレジストリに保存できます。

既存のコンテナから新しいイメージを作成できます。 コンテナに加えられた変更は最初にコミットされ、次にイメージがタグ付けされてレジストリにプッシュされます。

httpdコンテナを再度起動して、デフォルトのドキュメントを変更してみましょう。

  1. docker run -p 80:80 --name web -d httpd
  2. docker exec -it web /bin/bash
  3. cd htdocs
  4. echo '<h1>Welcome to my Web Application</h1>' > index.html
  5. exit

コンテナは、カスタマイズされたindex.htmlで実行されています。 curl localhostで確認できます。

変更されたコンテナをコミットする前に、それを停止することをお勧めします。 停止した後、commitコマンドを実行します。

  1. docker stop web
  2. docker commit web doweb

docker imagesコマンドでイメージの作成を確認してください。 作成したばかりのdowebイメージが表示されます。

このイメージにタグを付けてDockerHubに保存するには、次のコマンドを実行してイメージをパブリックレジストリにプッシュします。

  1. docker login
  2. docker tag your_docker_hub_username/doweb
  3. docker push your_docker_hub_username/doweb

ブラウザまたはコマンドラインからDockerHubを検索すると、新しいイメージを確認できます。

ステップ5—プライベートレジストリを起動する

プライベート環境でレジストリを実行して、イメージをより安全に保つことができます。 また、Dockerエンジンとイメージリポジトリ間のレイテンシーも削減されます。

Dockerレジストリは、他のコンテナと同じように起動できるコンテナとして利用できます。 レジストリには複数のイメージが保持されているため、ストレージボリュームをレジストリにアタッチすることをお勧めします。

  1. docker run -d -p 5000:5000 --restart=always --name registry -v $PWD/registry:/var/lib/registry registry

ポート5000が公開され、registryディレクトリがホストファイルシステムにマップされた状態で、コンテナがバックグラウンドで起動されることに注意してください。 docker psコマンドを実行すると、コンテナが実行されていることを確認できます。

これで、ローカルイメージにタグを付けて、プライベートレジストリにプッシュできます。 まず、DockerHubからbusyboxコンテナーをプルして、タグを付けましょう。

  1. docker pull busybox
  2. docker tag busybox localhost:5000/busybox
  3. docker images

前のコマンドは、busyboxコンテナがlocalhost:5000でタグ付けされていることを確認するため、イメージをプライベートレジストリにプッシュします。

  1. docker push localhost:5000/busybox

イメージをローカルレジストリにプッシュした状態で、イメージを環境から削除し、レジストリからプルバックしてみましょう。

  1. docker rmi -f localhost:5000/busybox
  2. docker images
  3. docker pull localhost:5000/busybox
  4. docker images

画像をプルし、タグを付け、ローカルレジストリにプッシュし、最後にプルバックするという完全な循環を実行しました。

専用ホストでプライベートレジストリを実行したい場合があります。 異なるマシンで実行されているDockerEngineは、リモートレジストリと通信して、イメージをプルおよびプッシュします。

レジストリは保護されていないため、安全でないレジストリにアクセスできるようにDockerEngineの構成を変更する必要があります。 これを行うには、/etc/docker/daemon.jsonにあるdaemon.jsonファイルを編集します。 ファイルが存在しない場合は作成します。

次のエントリを追加します。

/etc/docker/daemon.jsonを編集する
{
  "insecure-registries" : ["REMOTE_REGISTRY_HOST:5000"]
}

REMOTE_REGISTRY_HOSTをリモートレジストリのホスト名またはIPアドレスに置き換えます。 Docker Engineを再起動して、構成の変更が適用されていることを確認します。

##結論このチュートリアルは、Dockerの使用を開始するのに役立ちました。 インストール、コンテナ管理、イメージ管理、ストレージ、プライベートレジストリなどの重要な概念について説明しました。 このシリーズの今後のセッションと記事は、Dockerの基本を超えるのに役立ちます。