オウルです。
前回の続きになります。
Kubernetesを理解する上で、Dockerの基礎知識が必要となります。僕がDockerの知識ゼロのまま、勢いでKubernetesに突撃した結果・・・撃沈です。当然です、KubernetesはDockerありきですからね。この実体験からKunernetesをはじめてみたいという方は、Dockerの基礎だけでも知っているとよいかと思います。僕のように分からないことが分からないを回避するためにも、またKubernetes ⇒ Docker ⇒ Kubernetesの調べ方(誰の機能・役割なのか)もスムーズになります。
DockerはLinuxコンテナの技術を使用したコンテナ型仮想化技術です。
Linuxコンテナ
Linuxコンテナとは、Linux上で起動する各プロセスをコンテナのように壁を作り、隔離した状態で起動することです。この隔離を実現するためにLinuxカーネルの名前空間とcgroupの役割を知ることが重要になります。ではLinuxカーネルの名前空間とcgroupって一体何でしょうか。
名前空間、cgroupって何?
名前空間
・Cgroupプロセスのcgroup名前空間を分離するために、ルートディレクトリを扱う(Linux 4.6~)
・IPCSystem Vプロセス間通信(IPC:Inter Process Communication)とPOSIXメッセージキューを分離(Linux 3.0~)
・Networkネットワークデバイス、ルーティングテーブル、ファイアウォールルール、ポート等を分離(Linux 3.0~)
・Mountマウントポイント、ファイルシステムを分離(Linux 3.8~)
・PID実行するプロセスIDの分離(Linux 3.8~)
・UserユーザID(UID)とグループID(GID)の分離(Linux 3.8~)
・UTSホスト名(unameおよびhostnameコマンドで取得できる名前)の分離(Linux 3.0~)
cgroups
リソースの管理とリソースの集計/追跡を行います。これはLinuxカーネルの機能であり、プロセスの集まりに対し、リソース使用を制限/割り当て/分離します。
名前空間、cgroup の要約
Linuxカーネルの名前空間でプロセスを分離、cgroups(コントロールグループ)を使用してDockerコンテナを動作させるホストのCPU、メモリ、ネットワーク、ディスクI/Oなどのシステムリソースを制御するということです。
じゃ、この制御を具体的にどこに、どのように設定するの?という疑問はKubernetesでのコンテナデプロイで取り上げたいと思います。ここではコンテナをデプロイするときのマニフェストファイル(yamlファイル)にリソースを指定することができる、でとどめておきます。
Dockerイメージ
DockerイメージとはDockerコンテナ作成時に必要となるファイル群の総称であり、読み込み専用(read-only)のテンプレートです。
テンプレート
Docukerイメージはイメージレイヤのスタックです。この複数のイメージレイヤの集合体(積み重ね)を1つのファイルシステムとして見えるようにします。
nginxをdocker pull(レジストリからDockerイメージを取得)
「Pull complete」はイメージレイヤごとに並列でダウンロードしています。ではDockerfileを見てDockerイメージからコンテナをデプロイするイメージを掴んでみましょう。
Dockerfileって何?
Dockerfileは、Dockerイメージをアセンブルするためにコマンドラインで呼び出すことができるテキストドキュメント(Dockerイメージ構成ファイル)です。
分かりやすくいうとパブリックに公開されているDockerイメージ(Docuker Hub)に僕(ユーザー)が必要なパッケージやアプリケーション、ツール等を含めてオリジナルDockerイメージを作成する場合に、このDockerfileを使用します。次のDockerfileを見てみましょう。
Dockerfileを見る
このDockerfileは、Visual Studio 2017でASP.NET CoreプロジェクトのDockerを有効化した時に自動生成されるDockerfileです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
FROM microsoft/aspnetcore:2.0 AS base ⇒ (1) WORKDIR /app ⇒ (2) RUN ["echo","now base building..."] ⇒ (3) EXPOSE 80 ⇒ (4) FROM microsoft/aspnetcore-build:2.0 AS build ⇒ (5) WORKDIR /src COPY LinuxDockerAspNetCoreApp.sln ./ ⇒ (6) COPY LinuxDockerAspNetCoreApp/LinuxDockerAspNetCoreApp.csproj LinuxDockerAspNetCoreApp/ RUN dotnet restore -nowarn:msb3202,nu1503 ⇒ (7) COPY . . WORKDIR /src/LinuxDockerAspNetCoreApp RUN ["echo","now building..."] RUN dotnet build -c Release -o /app FROM build AS publish RUN dotnet publish -c Release -o /app ⇒ (8) FROM base AS final WORKDIR /app COPY --from=publish /app . ⇒ (9) RUN ["echo","now deploy..."] ENTRYPOINT ["dotnet", "MyAspNetCoreApp.dll"] ⇒ (10) |
(1)ASP.NET Core2.0をベースイメージとして使用します。どのDockerイメージもベースイメージを指定する必要があります。
●Alpineのベースイメージ
僕は、このベースイメージで初めてAlpineというLinuxディストリビューションを知ります。このAlpineは、セキュリティ・シンプルさ・リソース効率を重視するパワーユーザー向けに設計されているみたいです。すごく軽量です。
(2)作業ディレクトリを変更します。
(3)コンソールに出力します。
(4)80ポートで公開します。
(5)ASP.NET Coreのビルドイメージとして使用します。
(6)コピーします。
(7)プロジェクトの依存関係とツールを復元します。
(8)ホスティング システムへの展開のため、アプリケーションとその依存関係をフォルダーにパックします。
(9)–from=publishで直前のイメージを参照してコピーします。
(10)コンテナを実行するときの引数としてエントリーポイントに渡します。
DockerRegistryって何?
DockerRegistryにはパブリックとプライベートの考え方があります。
パブリック
Docker Hubのようにインターネット上に公開されているレジストリ
プライベート
オリジナルアプリケーションのようにインターネット上に公開すべきでないものを保持するレジストリ
パブリッククラウドには、このDockerRegistryサービスがあります。ただDockerRegistryサービス単体では利用シーンはないです。クラウドコンテナサービス等と連携して初めて威力を発揮するサービスです。
Azure Container Registry
Azureがサービス提供しているDockerレジストリです。
Amazon Elastic Container Registry
AWSがサービス提供しているDockerレジストリです。
Container Registry
Google Cloudがサービス提供しているDockerレジストリです。
Dockerコンテナ
当初、僕はLinuxコンテナはDockerコンテナのことを指していると思っていたのですが、違っていました。DockerコンテナとはLinuxコンテナの技術を使用したコンテナ型仮想化技術で、Dockerはこのコンテナ型仮想化を実現するランタイム(ソフトウェア)の1つです。
仮想化といえばHyper-V(Windows)、VirtualBox(Oracle)、VMwareの所謂、仮想マシンがお馴染みです。前回、docker for WindowsをインストールしてHyper-V(Windows)上に環境を作成しました。その環境もDockerコンテナを動作させるLinuxOSの仮想マシンです。コンテナ型仮想化は、仮想マシンとの比較がよく取り上げられます。ここでも簡単に比較してみましょう。
コンテナと仮想マシンの比較
何を抽象化するのか
アプリケーション層でコードと依存ファイルをパッケージした抽象化
物理ハードウェアの抽象化
起動速度
単にプロセス起動のため速い
OSのブートプロセスをエミュレートするため起動がコンテナに比べて遅い
Dockerコンテナのアプリケーションから見ると独立したコンピュータで動作しているように振る舞います。
読み書き可能なイメージレイヤ
Dockerのイメージ自体は起動されても更新は保存されず、明示的に保存(docker commit)をしなければコンテナ破棄時(docker rm)に変更分が消えてしまう仕様になっています。ん!?ちょっと待ってとなりますよね。Dockerイメージは、読み込み専用(read-only)のテンプレートではないの?となるはずです。では、Dockerコンテナを実行した時の下のイメージ図を見てください。
緑色のイメージレイヤが追加されています。DockerEngineは、Dockerコンテナ実行時にコンテナ用の読み書き可能なイメージレイヤを追加するのです。では、手を動かして確認してみましょう。
SQL Server on Linuxコンテナをデプロイして接続します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=HogeHoge!123" -d --name mssql mcr.microsoft.com/mssql/server:2017-latest Unable to find image 'mcr.microsoft.com/mssql/server:2017-latest' locally 2017-latest: Pulling from mssql/server 59ab41dd721a: Pull complete 57da90bec92c: Pull complete 06fe57530625: Pull complete 5a6315cba1ff: Pull complete 739f58768b3f: Pull complete 0b751601bca3: Pull complete bcf04a22644a: Pull complete dc7745d9cb0c: Pull complete ffbc09bb4f1a: Pull complete Digest: sha256:19b9392f035fc9f82b77f6833d1490bca8cb041b445cd451de0d1f1f3efe70e8 Status: Downloaded newer image for mcr.microsoft.com/mssql/server:2017-latest 56aebc332ae25c216f7ff2e078ee7c89b003315e15f700cd03f504b6321bdd05 |
docker runコマンドを実行して、最終行の「56aebc332ae25~」はコンテナIDです。では、このコンテナIDを指定してコンテナに接続します。
1 |
docker exec -it 56aebc332ae25c216f7ff2e078ee7c89b003315e15f700cd03f504b6321bdd05 /bin/bash |
コンテナに接続しました(SQL Server on Linuxコンテナの中)。次はSQLServerに接続して「TestDB」データベースを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
/opt/mssql-tools/bin/sqlcmd -S 127.0.0.1 -U sa -P 'HogeHoge!123' 1> select name from sys.databases 2> go name -------------------------------------------------------------------------------------------------------------------------------- master tempdb model msdb (4 rows affected) 1> create database TestDB 2> go 1> select name from sys.databases 2> go name -------------------------------------------------------------------------------------------------------------------------------- master tempdb model msdb TestDB (5 rows affected) |
「exit」でSQLServerからログアウトしましょう。今度は、データベースファイルが作成されているか確認します。
1 2 3 |
find / -name TestDB* /var/opt/mssql/data/TestDB_log.ldf /var/opt/mssql/data/TestDB.mdf |
作成されていますね。では「exit」で一度コンテナから抜けましょう。その後、一度SQL Server on Linuxコンテナを停止します
1 2 |
docker stop 56aebc332ae25c216f7ff2e078ee7c89b003315e15f700cd03f504b6321bdd05 56aebc332ae25c216f7ff2e078ee7c89b003315e15f700cd03f504b6321bdd05 |
再度、SQL Server on Linuxコンテナを開始します。
1 2 |
docker start 56aebc332ae25c216f7ff2e078ee7c89b003315e15f700cd03f504b6321bdd05 56aebc332ae25c216f7ff2e078ee7c89b003315e15f700cd03f504b6321bdd05 |
先ほどの手順で「TestDB」が存在しているか確認して下さい。停止したコンテナはスナップショットに保存され、「docker start コンテナID」で停止したdockerコンテナのスナップショットを再起動します。
本来であればデータベースファイルの永続化、ポート公開などの必要がありますが、それはKubernetessで紹介します。
コンテナが起動されない時
1 |
docker logs コンテナID |
docker のヘルプコマンド
1 |
docker --help |
コマンド一覧が表示されます。
1 |
docker run --help |
Docker のうれしいこと
単にプロセス起動のため速い。
動作させたいアプリケーションコードと依存ファイルをパッケージしてDocker Imageにしておけば、別の環境のDockerエンジン上でデプロイしても、振る舞いに差異がない。
この2点言葉にすると、ものすごくシンプルです。ですが、例えばアプリケーションの起動時間を短縮することが、どれほど大変で、また違う環境になった途端に訳の分からないエラーがでてガックシする現場レベルの人間からすると、マジで?!と思ってしまう、うれしいことではないでしょうか。
Dockerの特徴は「軽量」「携帯性」「揮発性」の3つのキーワードでよく表現されます。今回は「軽量」(起動速度が速い)「携帯性」(振る舞いに差異がない)について、うれしいことを紹介しました。「揮発性」については、Kubernetesでふれていきます。
いかがでしたか?僕はまだまだ分からないことがあるし難しい。しかし、パブリッククラウドでも Docuker をサポートするサービスが次々とリリースされており、身につけると自分の価値が高まるのは間違いないと思います。最後に僕がおすすめする書籍を載せていています。
おススメ書籍
技術本を読むなら Kindle がおすすめです。こちらの記事をご覧ください。
Docker の基礎(インストール、Docker Engine、Dockerfile etc)から実践的な活用方法まで知ることができる本になっています。初心者には適度なボリューム(本の厚さ)で、とっかかりとしては良い本になっています。
NoSQLはAWS、Azure、GCPで多様なサービスが提供されています。分散キャッシュとして使われる Redis も NoSQL の分類となります。特にRDBMS に慣れた人が、NoSQL を知るには良い本です。今やデータベースも、目的に応じて選択、組み合わせ(ハイブリッド)をするようになっています。
コンテナオーケストレーションプラットフォームである Kubernetes を学ぶときには、どうしても Docker の知識が必要となってきます。それをまとめているのが、この本です。途中で挫折しない適度なボリューム(本の厚さ)で、とっかかりとしては良い本になっています。