はじめに

本書を手にとっていただき、ありがとうございます。
本書は、Kubernetesのコアコンポーネントの1つである「Kubelet」の概要や実装、アーキテクチャについて著者が調査した内容をまとめたものです。

もともと著者はKubernetesのアーキテクチャに興味があり

  • Cloud Controller Manager(Kubernetesのコンポーネントの1つ)の内部実装や
  • Container Storage Interface(CSI)というKubernetesとストレージを連携するための仕様について解説したり
  • Kubernetes Internalという筆者が主催する勉強会で、筆者以外の方にもKubernetesのスケジューラーについても解説していただいたり

といったKubernetesのコンポーネントの内部実装の調査・共有会を普段から行っています。


その中でKubeletはKubernetesのコンポーネントの中でも国内外で最も情報が少ない印象で、内部実装に関するまとまった情報がほとんど無い印象でした。また、Container Runtime Interface(CRI)を通してコンテナランタイムと連携を行ったりと複雑な処理を行っている印象であったため、どうせだったら本にして情報をまとめたいと思ったのが本書を書こうと思ったきっかけです。


実際にKubeletの実装を読んでいくと、コンテナやその他関連するリソースの状態を宣言された状態に調整するために、様々なアプリケーションがKubeletの内部で動作していることがわかり、思っていた以上に複雑な構造をしていることがわかりました。

そのため、本書では図を多く使用してなるべくKubeletの全体像をイメージしていただけるように書いていますが、わかりづらいところや質問がありましたら筆者のTwitterアカウント(https://twitter.com/bells17_)までご連絡いただければと思います。


また、この本を執筆する過程で作成した資料も以下で公開していますので、良ければ参考資料としてご利用ください。

この本の想定読者

この本のメインとなる内容がKubernetesのコアコンポーネントであるKubeletがどのように動作するのか?ということの解説になるため

  • KubernetesやKubeletが裏側でどう動いているのか?に興味がある方
  • Kubernetesの内部実装に興味がある方

が主な想定読者となるのではないかと思っています。


また、本書では

  • Kubernetesの基本的な使い方
  • 基本的なGo言語の書き方

については大まかにでも知っている・理解しているという前提で話を進めて行きます。

調査を行ったKubernetseバージョンや動作についての環境

著者が調査を行ったKubernetesバージョンや調査した動作についての前提について記載します。2020年12月時点のものです。

  • Kubernetes v1.19 *1
  • Linuxで動かすことを想定
  • Cloud Probiderは利用しない、またはexternalである想定
  • その他は特にKubeletのオプションやconfigを設定していない想定 *2

注意事項

  • 本書の内容はあくまで著者がKubeletのコードベースを中心に調査した内容が主となります。そのため内容に間違いなどが含まれる可能性があることをご了承ください。
  • 紹介記事などについてはリンクを張っていますので、ブラウザを開くことのできる端末で読んでいただいた方が良いかと思います。

免責事項

本書に記載された内容は、情報の提供のみを目的としています。したがって、本書を用いた開発、製作、運用は、必ずご自身の責任と判断によって行ってください。これらの情報による開発、製作、運用の結果について、著者はいかなる責任も負いません。

表記関係について

本書に記載されている会社名、制限名などは、一般に各社の登録表彰または商標、商品名です。 会社名、製品名については、本文中では©、®、™マークなどは表示していません。


[*2] 設定値のデフォルトは主に https://github.com/kubernetes/kubernetes/blob/release-1.19/pkg/kubelet/apis/config/v1beta1/defaults.go で設定されているようです

目次

はじめに

この本の想定読者
調査を行ったKubernetseバージョンや動作についての環境
注意事項
免責事項
表記関係について

第1章 Kubernetesの概要

1.1 Kubernetesクラスターの構成
  • 1.1.1 etcd
  • 1.1.2 Control Plane
  • 1.1.3 Worker Node

第2章 Kubeletの概要を理解する上で事前に知っておくと良いこと

2.1 StaticPod/MirrorPod
2.2 コントローラーとReconcilation Loop
2.3 Go言語のgoroutineとチャネル

第3章 Kubeletの概要とメインループ

3.1 Kubeletの全体像
3.2 Podの調整処理
  • 3.2.1 Pod調整処理の大まかな全体像
  • 3.2.2 podConfig.updates
  • 3.2.3 ハンドラー ~ コンテナ起動までのフロー
  • 3.2.4 syncCh
  • 3.2.5 Pod Lifecycle Event Generator(PLEG)
  • 3.2.6 Liveness Probe.Update
  • 3.2.7 housekeepingCh

第4章 Kubeletが起動するWeb Server

4.1 Kubelet Server
4.2 Healthz Server

第5章 その他独立して動作するマネージャーやコントローラーについて

5.1 syncNodeStatus
5.2 NodeLeaseController
5.3 dynamicKubeletConfigController
5.4 Plugin Manager
5.5 clientCertificateManager

第6章 dockershimとContainer Runtime Interface(CRI)について

6.1 Container Runtime Interface(CRI)について
6.2 dockershimとは?

あとがき

レビュワーの方々

参考資料

奥付

第1章 Kubernetesの概要

まずはじめに、そもそもKubernetesとは?というところについて簡単にまとめてからKubeletの話に入っていこうと思います。


Kubernetesはいわゆるコンテナオーケストレーターの1つで、簡単に言ってしまえばコンテナをいい感じに起動・管理を行うことができ、動作させているコンテナとネットワークやロードバランサーなどを簡単に連携することができるソフトウェアです。

Kubernetesの最も特徴的な部分として、宣言的アーキテクチャであるということが話に出ることが多いです。

宣言的アーキテクチャは、Kubernetesで言うと「こんなコンテナをx台立ち上げてほしい」ということをmanifestファイルと呼ばれるもので記述し、それをKubernetesに適用すると、Kubernetesは記述されたmanifestファイルの内容に基づき指定されたコンテナをx台起動してくれるような仕組みを指します。

また、対象のコンテナが何らかの理由で停止してしまった場合には、Kubernetesが自動的にx台になるようにコンテナ数を調整してくれます。

これがKubernetesにおける宣言的アーキテクチャの特徴です。

1.1 Kubernetesクラスターの構成

Kubernetes は1台以上のサーバーでクラスターを構築して動作します。そのサーバーは大きく以下の3種類に分けられます。

  • etcd
  • Control Plane
  • Worker Node
Kubernetesの全体像

図1.1: Kubernetesの全体像

1.1.1 etcd

etcdはKubernetesのデータストアとして、先程登場したmanifestファイルから適用された各種リソース情報を保存するために利用されます。

ちなみに、kubeadmなどを使ってKubernetesクラスターを構築すると、etcdやControl PlaneはKubernetesクラスターのノード上に構築されますが、Control PlaneやetcdはKubernetesのWorker Nodeの外で実行することも可能です。
(Kubernetesのマネージドサービスはこういった構成を取っているのではないかという気がしています)

1.1.2 Control Plane

Control PlaneはKubernetesクラスターを動かすためのいくつかのコンポーネントのことで

  • API Server
  • Kube Controller Manager
  • Cloud Controller Manager
  • Scheduler

の4種類があります。

API Server

API Serverはkubectlやclient-go*1といったSDKを通してリクエストを受けるAPI Serverです。Kubernetesに関する操作は基本的に全てこのAPI Serverを経由して行われ、データストアであるetcdへの接続もこのAPI Serverを通してのみ行われます。


API Serverにはリソースに関する操作をフックするAdmission Webhookという仕組みがあります。
(https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/)

Admission Webhookには

  • リクエストされたデータの書き換えを行うMutating Webhook
  • リクエストされたデータのバリデーションを行うValidating Webhook

の2種類があり、登録・更新されるKubernetesのリソースのバリデーションや値の書き換え操作が可能となっています。


また、API ServerにはExtension API ServerというAPI Serverを独自に拡張する方法が提供されており、Kubernetesの https://github.com/kubernetes/sample-apiserver リポジトリでサンプルのExtension API Serverが提供されているので、興味がある方はこちらを試して見ていただければと思います。

Kube Controller Manager

Kube Controller ManagerはKubernetesの各種リソースをもとに宣言された状態に調整するコントローラーというものをまとめて実行するコンポーネントです。現時点で30を超えるコントローラーがこのKube Controller Manager上で実行されているようです。


例えば、Deploymentリソースを作った際にReplicaSet~Podリソースが作成されるのは

  • Deployment Controller
  • ReplicaSet Controller

といったコントローラーがKube Controller Managerの内部で動いているからです。これらのコントローラーによってReplicaSetやPodリソースが作成されています。

Cloud Controller Manager

Cloud Controller Managerは、Kube Controller ManagerからKubernetesクラスターが動くIaaSと連携するための4つのコントローラーをまとめたものになります。


具体的には

  • パブリッククラウドやVMware、OpenStackといったIaaSと連携して登録されたWorker Nodeの設定
  • Serviceリソースと呼ばれるKubernetesのリソースと連携して、IaaS側のL4ロードバランサーを構築~構築したL4ロードバランサーからKubernetesクラスター上で実行されているPod(コンテナをグルーピングした実行単位)への経路を確保

といった機能がCloud Controller Managerを介して実行されます。


Cloud Controller Managerは対象の実行環境向けのCloud Providerと呼ばれる、IaaSと連携するためのインターフェイスを満たしたパッケージと連携することで、IaaSとの連携を実現するコントローラー群になります。


上記のような機能をCloud Providerを利用して実現するために、Cloud Controller Managerでは

  • Node Controller
  • Node Lifecycle Controller
  • Route Controller
  • Service Controller

という4つのコントローラーを実行します。

Cloud Controller Managerの全体像

図1.2: Cloud Controller Managerの全体像

この図のようなイメージで各コントローラーがそれぞれ必要な処理をCloud Providerのインターフェイスを通して実行環境に要求し、処理を行います。

Cloud Controller Managerの詳細については

で解説を行っていますので、こちらをご覧ください。

Scheduler

SchedulerにはPodをどのWorker Nodeで実行するのかを選定するロジックが入っています。通常のWebアプリケーションを利用しているだけだと、あまり意識することは少ないですが、例えばKubernetesを機械学習基盤に利用する際には、このSchedulingの最適化を行うために、独自にSchedulingロジックを入れたりする事例をよく耳にします。


SchedulerにはScheduling Frameworkというスケジューリングの仕組みを独自に拡張していける仕組みがあるようで、こちらについては以前チェシャ猫さん(https://twitter.com/y_taka_23)がKubernetes Internal #3(https://youtu.be/TRy_SZQ53Ao)で行っていただいたセッションで詳細が解説されていますので、興味があればご覧ください。

1.1.3 Worker Node

Worker Nodeでは

  • kube-proxy
  • Kubelet

の2種類のコンポーネントが動作します。

kube-proxy

kube-proxyはWorker Nodeのネットワーク設定を行うコンポーネントです。具体的には、KubernetesのServiceリソースの

  • type: ClusterIP
  • type: NodePort

の2種類(つまりtype: LoadBalancer以外)から生成されるEndpoint/EndpointSliceというリソースに基づいて、NodeとPodの通信経路を制御します。

Kubelet

最後にKubeletです。これが本書でメインで扱っていくコンポーネントになります。

KubeletはKubernetesのコアコンポーネントの1つで、各Worker Nodeで動作します。 Kubeletは実行されているNode(サーバー)で動作し

  1. Kubeletを実行しているサーバーをKubernetesのWorker Nodeとして登録・管理する
  2. 実行しているWorker Nodeで実行すべきPod(コンテナ)情報を取得し、実行する

ということを主に実行します。

これらの詳細について、次章以降で説明していきたいと思います。


試し読みはここまでです。
この続きは、製品版でお楽しみください。