最近のトレンドはKubernetesらしく、遅れを取らないように勉強しようと思いました。
ただ、Kubernetesの最初の一文にやられてしまいました。
Kubernetesはコンテナ化されたアプリケーションのデプロイ、スケーリング、および管理を自動化するためのプラットフォームです。
そもそもコンテナをあまり勉強していなかった。。
まずは、そこから概要レベルでおさらいしてみますか。
(Dockerのイメージを公式から取ってきて、なんとなく動かしていたレベルです。)
今回はDockerの概要を復習することで、Kubernetesのスタートラインに立てることを目的とします。
本記事について
復習にあたり
Dockerは、コンテナを実行するための実行環境(コンテナランタイム)およびツールキットです。
一応、KubernetesはDocker以外のコンテナランタイムにも対応しているようです。
なので、Docker独自のものまでではなく、コンテナの概要を理解するためにDockerを見ていくようにします。
まあ、Dockerの普及率は非常に高いらしいので、大丈夫だとは思いますが。
復習する範囲
今回は、Dockerの以下の項目について見ていきます。
- Dockerコンテナの設計
- Dockerfileの書き方
- Dockerイメージのビルド
Dockerコンテナとは
Dockerコンテナは、Dockerイメージをもとに実行されるプロセスです。
Dockerイメージは、どの環境で動かしても実行結果が変わらない特徴があります。
Build Once, Run Anyware
かっこいいですね。
[plantuml]
@startuml
actor Developer
Developer -right-> [ContainerImage] :コンテナイメージのビルド
note right
一度ビルドしたコンテナイメージは
どこで実行しても実行結果は変わらない
end note
[ContainerImage] -down-> [Ubuntu]
[ContainerImage] -down-> [CentOS]
[ContainerImage] -down-> [Windows]
[ContainerImage] -down-> Cloud
cloud "Cloud" {
}
@enduml
[/plantuml]
また、仮想マシンと比べて、「軽量」、「高速な起動と停止」という特徴もあります。
仮想マシンはゲストOSを起動して動作させる必要がありますが、Dockerコンテナはホストマシンのカーネルを利用したまま、名前空間の分離やらcgroupsを使った制御やらで独立したOSのような環境を実現しているようです。
ゲストOSがないぶん、そこに左右されないので高速になっているってことですかね。
Dockerコンテナの設計
Dockerコンテナの特徴を理解すると、作成するときに気をつけないといけないことが見えてきます。
主に以下の4つです。
- 1コンテナに1プロセス
- Immutable Infrastructure(不変なインフラ)なイメージにする
- 軽量なDockerイメージにする
- 実行ユーザをroot以外にする
1コンテナに1プロセス
これはとても大事らしいです。
仮想マシンでは、ホストOSとゲストOSではっきり分かれていたので複数プロセスOKでしたが、Dockerコンテナはホストマシンのカーネルを利用したまま
の特徴があるためですね。
Immutable Infrastructure(不変なインフラ)なイメージにする
一度ビルドしたコンテナイメージはどこで実行しても実行結果は変わらない
特徴のためです。
コンテナ起動後に、外部からパッケージインストールしたりすると、コンテナイメージの実行結果が変わってくるからです。
コンテナイメージに実行バイナリやパッケージをできる限り埋め込んで、バージョン管理で整理しておき、コンテナイメージは不変な状態にしておきます。
軽量なDockerイメージにする
Dockerを使ってて、外部からpullする時に容量が大きいと嫌だったのをなんとなく思い出しました。
以下のような例を参考にして、軽量化しておきましょう。
- yumやaptなどでパッケージをインストールした後のキャッシュファイルやリポジトリのパッケージリストを削除
- ベースイメージを軽量なディストリビューションを使う
実行ユーザをroot以外にする
実行ユーザの実行権限を最小化しておこうってことですね。
Dockerfileの書き方
Dockerイメージは、Dockerfileをもとにイメージがビルドされます。
Dockerイメージの作成手順書と捉えておくといいかもしれません。
例を書いてみます。
HTTPリクエストがきたらmain.go
を実行するコンテナイメージです。
# alpine 3.7ベースのgolang 1.10.1のイメージをベースとして使用
FROM golang:1.10.1-alpine3.7
# 8080ポートを
EXPOSE 8080
# ビルドを行うマシン上のmain.goファイルをコンテナにコピー
COPY ./main.go ./
# コンテナ内でコマンドを実行
RUN go build -o ./go-app ./main.go
# 実行ユーザをnobodyに変更
USER nobody
# コンテナ起動時に実行するコマンドを定義
ENTRYPOINT ["./go-app"]
命令 | 意味 |
---|---|
FROM | ベースとするDockerイメージ |
EXPOSE | コンテナがListenするポート |
COPY | ビルドを行うマシン上のファイルをコンテナにコピーして配置 |
RUN | ビルド時にコンテナ上でコマンド |
USER | 実行するユーザ |
ENTRYPOINT | コンテナ起動時に実行するコマンド |
基本的な流れは、FROMで指定したベースイメージに対して、RUNやCOPYなどでパッケージのインストールやファイルの配置などで、イメージを作成していきます。
Dockerイメージのビルド
先ほど作成したDockerfileをもとにdocker build
コマンドでイメージをビルドします。
-t
オプションでイメージの名前とタグを指定することができます。