『イラストでわかるDockerとKubernetes』を読んだ

どんな本か

この本はタイトルどおりイラストを交えてDocker・Kubernetesについて分かりやすく説明された本です。

構成は以下の通りで、ページ数も130ページ程度なのでサクッと読めるようになっています。

  • 第1章 コンテナ技術の概要
  • 第2章 Dockerの概要
  • 第3章 Kubernetesの概要
  • 第4章 コンテナランタイムとコンテナの標準仕様の概要

目的

普段はローカル環境でDockerを使ったり、本番環境にAWSのAmazon ECSを導入してみたりはしましたが、Kubernetesは全くさわってきませんでした。

最近ふとKubernetesを実際にさわってみて、仕事に活かしたりできないかと思い、この本を手に取りました。

「まずはKubernetesやその周辺技術の概要をざっくりで良いので掴みたい」というのが目的です。

感想

Kubernetesの仕組みやより踏み込んだコンテナランタイムや標準仕様などの説明が分かりやすく、個人的にすごく面白かったです。 特にkubelet、CRIランタイム、CNIプラグイン、OCIランタイムらへんはもっと深堀りしてみたい。

要所要所にイラストや実際に実行したコマンドの結果を載せてくれているので、手を動かさずに読み進めても雰囲気で理解できますが、一度Kubuernetesの環境構築をしたほうが良さそうです。 あと、実際に使う場合、Amazon EKSやGoogleのGKEを利用すると思うので、そこらへんの構築も試して手順として残しておきたいところ。

以下の本は初めてKubernetesさわる人が読むと良いらしいとTwitterで見たので、次はこれを読みつつ手を動かしていこう。

あと、以前聞いたfukabori.fmのdocker/kubernetes周りのネットワーキングの話も改めて聴く。

fukabori.fm

eh-career.com

読書ノート

第1章 コンテナ技術の概要

  • コンテナもその実態はプロセスで、異なるのはOSカーネルの機能を用いて通常のプロセスよりもより強く環境が隔離されている点

第2章 Dockerの概要

  • コンテナイメージの作成
    • Dockerfile: コンテナの作成手順書
    • コンテキスト: コンテナに格納するプログラムなどのファイル群
  • コンテナイメージのレイヤ構造
    • レイヤ(変更差分)
    • コンテナは変更差分を集めたもの
  • コンテナのレイヤ構造は、その実行時にも保たれている
  • コンテナのレイヤ構造は、コンテナ同士で可能な限りデータの重複を作らないようにしつつ、お互いの環境が影響し合わないようにする
  • あるイメージからコンテナを複数実行する場合でも、それらコンテナ同士で共通のレイヤ群はコピーされることなく、共有される
  • Storage Driverは、コンテナを構成する各レイヤをホスト上で保持しており、それらを重ね合わせてコンテナのルートファイルシステムとして利用できるようにするなど、レイヤ群の管理を担うコンポーネント
    • 実装は、aufs, btrfs, overlayfsなど、さまざまなファイルシステムなどの技術が用いられている
  • overlayファイルシステムはLinuxカーネル3.18から導入され、あるディレクトリを別のディレクトリへ重ね合わせ、その重ね合わせた結果をマウントすることができるファイルシステム
  • マシン上ではDockerデーモン(dockerd)が起動しており、dockerコマンドからDocker APIと呼ばれるHTTP API経由で支持を受ける
  • Dockerデーモンは、コンテナの実行だけでなく、そのイメージやネットワーク、ストレージなどコンテナのライフサイクル全体にわたる管理を担っている
  • ホストから隔離された実行環境をコンテナとして作り出したり、それを直接操作するのはDockerデーモンではなく、OCIランタイム(低レベルランタイム)と呼ばれるソフトウェアが担当する

第3章 Kubernetesの概要

  • Kubernetesに対して「アプリケーションやそれを構成するコンテナ群はこういう状態であるべき」というような理想状態をYAMLやJSON形式の「マニフェスト」と呼ばれる設定ファイルの形で宣言すると、それを実現・維持するための具体的な作業をKubernetesがよしなに行ってくれるというもの。
  • Kubernetesは管理情報をHTTP APIで公開しており、ユーザはそのAPIの操作を通じて前節で述べたような理想状態の宣言や、アプリケーションに関する状態の確認などを行う
    • このAPIを参照・操作しながら、ユーザーが宣言した理想状態を維持するために具体的な管理作業を行うコンポーネント群は「コントローラ」と呼ばれる
  • コンテナ群を実行するマシンの集合を「クラスタ」と呼ぶ
  • 各コンテナが実行されるマシンは「ノード」と呼ぶ
  • ノード上では複数の「ノードコンポーネント」が稼働し、そのノード上のコンテナ群の実行管理やイメージの管理、通信の管理などを行う
  • Kubernetesクラスタ全体の管理を担うコンポーネントは「コントロールプレーン」と呼ぶ
    • コントローラーやコンテナのデプロイ時にそのスケジューリングを行うコンポーネントなどが含まれる
  • Kubernetesにおいて最も基本的なデプロイ単位は関連する複数のコンテナ群を1つにまとめた「Pod」と呼ばれているもの
  • 1つのPodに含まれるコンテナ群は同一のノード上にデプロイされ、ネットワーク・インターフェースやストレージの割当などを共有する
  • KubernetesはIPアドレスをPodごとに払い出すため、Pod同士はそれぞれのIPアドレスを使って通信できる。またPod内のコンテナはlocalhostで通信できる。
  • Pod群のデプロイにまつわるリソース
    • Deployment
      • Pod群を一定数を維持しながらクラスタ上に展開するのに有用なリソース
      • セルフヒーリング
        • 障害の発生などによりクラスタ全体で設定された数のPodが正常に稼働していない場合に、自動敵に新たなPodを実行し復旧を試みる機能
      • スケーリング
    • StatefullSet
      • ステートフルなコンテナの実行をサポート
      • Podにはインデックス0を含むPod名と固有のボリューム)PersistentVolume)が付与される
    • DeamonSet
      • 各ノード上にPodが1つずつ実行されている状態を維持するリソース
    • Job
      • 単発に実行するユースケースに有効
    • CronJob
      • Conフォーマットで実行開始時間や定期実行など設定可能
  • Podやコンテナは、長期的な状態を持たないステートレス、またはエフェメラルな(揮発性の)実行単位と言われる
  • 設定項目・秘匿項目を独立して管理できるように、ConfigMapやSecretというリソースがある
    • コンテナ内の環境変数としてみせる
    • コンテナ内のファイルシステムに読み取り専用でマウントし、ファイルとして見せる
  • Service
    • あるサービスを提供する複数のPodに共通のIPアドレスを付与し、1つの「サービス」のようにアクセスできるようになる
    • Pod自体にもIPアドレスが付与されているが、Serviceが必要なのはなぜか?
      • Kubernetes上ではPodのIPアドレスは頻繁に変わり得るという点が挙げられる
    • リソースの種類
      • NodePort
        • 各ノード上のポートをクラスタ外に公開し、そのポートを通じた通信を、そのServiceを構成するPodのいずれかにロードバランスする。
      • Load Balancer Service
      • Ingress
        • L7ロード・バランシングの機能を提供する
        • 1つのアプリケーションを複数のServiceを用いて構成し、URLのホスト名やパスのルールベースで、実際にアクセス先として用いる
  • kubelet
    • ノード上のPod群の実行管理を行う
  • CRIランタイム
    • イメージの取得やPod・コンテナ群の管理を行う
  • CNIプラグイン
    • Podの作成はCRIランタイムが担当するが、そのPodにIPアドレスを払い出し、仮想的なNICをPodに付与するのはCNIプラグインが行う
      • flannel, Calico
  • OCIランタイム
    • CRIランタイムなど高位のランタイムから指示を受け、ホストから隔離された実行環境をコンテナとして作り出しその直接操作の手段を与える

第4章 コンテナランタイムとコンテナの標準仕様の概要

  • containerd
    • Dockerはコンテナ実行のためにcontainerdを内部で使用している
    • containerdはCRIを実装しているため、Kubernetes環境ではcontainerdを単体のCRIランタイムとして用いることができる
    • containerdが低レベルランタイムを呼び出すときは、shimと呼ばれるバイナリコンポーネントを介する。低レベルランタイムは、それぞれの持つアーキテクチャに合ったshimを実装し、それをcontainerdにプラグインすることで、containerdを通じてそれら低レベルランタイムを操作できるようになる。
  • 低レベルランタイムはOCIで定義されたインターフェースを通じて高レベルランタイムから指示を受け、ホストから隔離された実行環境を作成したり、その操作手段を提供する
    • コンテナ(ホストから隔離された実行環境)の作り方は1つではなく、低レベルランタイムによってさまざなバリエーションがある。
    • runc, gVisor, Kata Containersas
  • OCI Runtime SpecificationはOCIによって策定されている低レベルランタイムの仕様のこと
  • Filesystem bundle
    • ファイル群が格納されたディレクトリ
      • コンテナのルートファイルシステム
      • コンテナ実行環境の設定ファイル
  • コンテナのライフサイクル
    1. Filesystem bundleをOCI準拠のランタイムに指定し、コンテナを作成
    2. コンテナの実行を開始
    3. コンテナ内のアプリケーションが終了する
    4. コンテナを削除する
  • コンテナに対して可能な操作
    • create
    • start
    • kill
    • delete
    • state
  • OCI Image Specification
    • マニフェスト
    • レイヤ
    • コンフィギュレーション
    • インデックス(optional)
  • namespace
    • あるプロセスから操作可能なリソースを、その他のプロセスから隔離できる機能
    • PIC namespace プロセス群の管理
    • Mount namespace マウントポイントリストの隔離
    • Network namespace ネットワーク関連のリソースの隔離
  • cgroup
    • プロセスが使用可能なリソースについて、たとえば以下を含むさまざまな設定を施せる機能
    • デバイスファイルへのアクセス権限
    • プロセスから利用可能なCPUの制限
    • プロセスが利用可能なメモリ使用量の制限