Kubernetesを構成するコンポーネント郡#

コンポーネント 種別 説明
etcd 🔗 master Kubernetesのリソースの永続化に使われる高信頼分散KVS
kube-apiserver master Kubernetesのリソースを管理するAPIサーバー
kube-scheduler master Podのノードへの割り当てを行うスケジューラー
kube-controller-manager master Replication Controllerなどの各種コントローラーを起動し管理するマネージャー
kubelet node Podを起動し管理するエージェント(Nodeのメイン処理)
kube-proxy node KubernetesのServiceが持つ仮想的なIPアドレス(cluster IP)へのアクセスをルーティングする
container-runtime node コンテナの実行形態で多くの場合はDockerが使用されている
kubectl client KubernetesのCLIクライアント
pause misc pod内のネットワークnamespaceを保持するコンテナ
pod-master add-on High-Availability構成時にscheduler, controllerがどのMasterで動くかを調整するコンテナ
kube-dns add-on クラスタ内DNSのPod
SkyDNS 🔗 add-on クラスタ内DNSのDNSサーバー
kube2sky add-on SkyDNSにKubernetesの情報を反映させるブリッジ
heapster add-on Kuernetesのパフォーマンス情報を集約する仕組み

注釈

🔗 マークは外部のプロジェクト

アーキテクチャ#

architecture

Masterコンポーネント#

etcd 🔗#

graph BT; subgraph master; A(kube-apiserver)-->E(etcd); end

etcdはKubernetesのリソースの永続化に使われる高信頼分散KVSです。etcdはKubernetesのリソース以外にも、後述のSkyDNS、pod-masterなどの保存の用途にも使われています(etcdのインスタンスは一般的に別になります)。

etcdのキーはパス形式になっており、API Serverの--etcd-prefixオプション(デフォルトは/registry)で指定したディレクトリ以下に保存されます。。また--etcd-servers-overridesオプションでリソースの種類ごとにetcdのサーバーを変えることも可能です。大規模環境においてはEventsリソースは量が多いため、etcdインスタンスを別にすることが推奨されています。詳細はKubernetesマニュアルのkube-apiserverUsing Large Clustersの項を参照ください。

etcdはLinuxコンテナ向けdistroのCoreOSを開発する、CoreOS社が開発しています。

参考

参考: etcdに保存されているデータのサンプル#

Kubernetesリソースのetcdのキーは以下のように保存されています。

# etcdの"/registry"以下のキー名を表示
$ etcdctl ls --recursive /registry
# サンプルを抜粋
/registry/namespaces/default
/registry/namespaces/kube-system
/registry/secrets/default/default-token-qfomx
/registry/secrets/kube-system/default-token-bf0m1
/registry/minions/172.17.4.101
/registry/minions/172.17.4.201
/registry/pods/kube-system/kube-controller-manager-172.17.4.101
/registry/pods/kube-system/heapster-v10-ut5ls

valueにはリソースのJSON文字列がそのまま入っています。

$ etcdctl get /registry/ranges/serviceips | jq .
{
  "kind": "RangeAllocation",
  "apiVersion": "v1",
  "metadata": {
    "creationTimestamp": null
  },
  "range": "10.3.0.0/24",
  "data": "IAAACAAAAAAIAAAAAAAAAAAAAAAAAAABAAAAAAADAQ=="
}

kube-apiserver#

graph BT; C(kubectl)-->A; subgraph master; A(kube-apiserver)-->E(etcd); S(kube-scheduler)-->A; M(kube-controller-manager)-->A; end; subgraph node; L(kubelet)-->A; P(kube-proxy)-->A; end;

KubernetesのAPIサーバーで、主にKubernetesのリソース情報の管理を担っています。基本的にリソース情報のCRUD処理のみを行い、リソースに対する実際の処理やスケジューリングは別のコンポーネント(kube-controller-managerkube-scheduler)が行います。リソースの状態はすべてetcdに保存されます。APIサーバー以外のコンポーネントは直接etcdを参照せず、APIサーバーを通してリソースにアクセスします。kubectlコマンドも、APIサーバーへのアクセスを通して操作を行っています。

認証、認可の他に、Admission Control (参考: Kubernetes: Admission Controlとは何か) というリクエスト制御の仕組みを備えています。

水平スケールさせることが可能なコンポーネントです。

参考

kube-scheduler#

新しく作られたPodのノードへの割り当てを行うスケジューラーです。Kubernetes APIを通して、Pod, Nodeなどのリソースをwatchし、bindings APIでNodeとPodのひも付けを行います。スケジューラのポリシーは設定可能で、--policy-config-fileという起動オプションで設定のjsonファイルを指定します。(参考: scheduler-policy-config.json)

Podの要求しているリソースやNodeのリソースの使用率などをみて適切なNodeを1つ選択し、PodをNodeに紐付ける(スケジュールする)。

参考

kube-controller-manager#

Kubernetesの各種リソースのコントローラーを起動するマネージャーです。

graph TD; A(kube-controller-manager)-->D(Deployment); A-->S(Service); A-->C(CronJob); A-->R(ReplicaSet); A-->X(...);

各コントローラーはgoroutineで起動されます。(参考: controllermanager.go#L185-L390)。

Note

Replication Controllerはリソース名自体に"Controller"とつくため、コントローラーは"RepplicationManager"という名前になっています。(参考: replication_controller.go#L63-L64のコメント)

下記はkube-controller-managerをpprofで見た、goroutineで起動する各コントローラーに関する処理の一覧です。

k8s.io/kubernetes/pkg/controller/daemon.(*DaemonSetsController).Run
k8s.io/kubernetes/pkg/controller/deployment.(*DeploymentController).Run
k8s.io/kubernetes/pkg/controller/endpoint.(*EndpointController).Run
k8s.io/kubernetes/pkg/controller/gc.(*GCController).Run
k8s.io/kubernetes/pkg/controller/job.(*JobController).Run
k8s.io/kubernetes/pkg/controller/namespace.(*NamespaceController).Run
k8s.io/kubernetes/pkg/controller/node.(*NodeController).Run
k8s.io/kubernetes/pkg/controller/persistentvolume.(*PersistentVolumeClaimBinder).Run
k8s.io/kubernetes/pkg/controller/persistentvolume.(*PersistentVolumeRecycler).Run
k8s.io/kubernetes/pkg/controller/podautoscaler.(*HorizontalController).Run
k8s.io/kubernetes/pkg/controller/replicaset.(*ReplicaSetController).Run
k8s.io/kubernetes/pkg/controller/replication.(*ReplicationManager).Run
k8s.io/kubernetes/pkg/controller/resourcequota.(*ResourceQuotaController).Run
k8s.io/kubernetes/pkg/controller/serviceaccount.(*ServiceAccountsController).Run
k8s.io/kubernetes/pkg/controller/serviceaccount.(*TokensController).Run

参考

Nodeコンポーネント#

kubelet#

Quote

kubelet はPodを起動、管理するエージェントだ。

kube-scheduler によって紐付けられた(スケジュールされた)Podをkubeletが認識して、そのPodを自身のNodeで起動させる。 また、実行しているPodの監視・管理も行う。

なので、実際にコンテナのワークロードを発行しているのはこの kubelet だ。

kubeletは各ノードで動作するエージェントで、Nodeのメイン処理であるPodの起動・管理を行います。起動するPodの情報は、APIサーバーを監視して自ノードに割り当てられたものを見るのが主ですが、他にも下記の3つの方法が用意されています。この仕組みを使うことでAPIサーバーを含むMasterコンポーネントも、kubelet上で動作させることが可能です。

  • ローカルファイル ノードの特定のディレクトリ(例えば/etc/kubernetes/manifests)を監視し、そこに置かれたマニフェストファイルに書かれたPodを起動します。監視するファイルまたはディレクトリは--configオプション、監視間隔は--file-check-frequencyオプション(デフォルトは20秒)で指定します。
  • HTTPエンドポイント 特定のURLを監視し、そこに置かれたマニフェストファイルに書かれたPodを起動します。監視するURLは--manifest-urlオプション、監視間隔は--http-check-frequency=オプション(デフォルトは20秒)で指定します。
  • HTTPサーバー Kubelet自体持つのHTTPサーバーに対して、マニフェストを送信する方法です。

参考

kube-proxy#

kube-proxyはKubernetesのServiceオブジェクトを元にルーティングを行う。

実体はiptablesのルールを発行し、パケットの制御を行っている。

この実装は切り替えることができ、以下の中から選択できる。

  • userspace
  • iptables
  • ipvs(experimental)

デフォルトでiptablesが使われる。

参考

Container Runtime#

graph TB; subgraph node; L(kubelet)-->D(container-runtime); end

Cotainer Runtimeはkubeletからの呼び出され、コンテナの実行をする。

KubernetesではこのContainer Runtimeを差し替えることが出来る。 他のContainer Runtimeは以下のようなものがある。

  • Docker
  • containerd
  • cri-o
  • gVisor
  • Kata Containers

大抵のKubernetesのマネージドサービスではDockerが使用されている。 (実際の所Dockerの中身はcontainerdだ)

その他のコンポーネント#

Pauseコンテナ#

PauseコンテナはPod内のネットワークネームスペースの情報を保持する特別なコンテナで、すべてのPodに自動的に付加されます。Kubernetes内部ではPodInfraContainerImageという定数で特別扱いされており、PauseコンテナだけがPod内でネットワークネームスペースの情報を保持し、他のコンテナはそれを共有する方式を取っています。(参考: pkg/kubelet/dockertools/manager.go)。これによりPodの他のコンテナがkillされたとしてもネットワークネームスペースの情報を保持しておくことができます。Pauseコンテナ自体は文字通りpauseシステムコールを呼び出すだけで何もしません。(参考: pause.asm#L47)。Pauseコンテナはkubeletの--pod-infra-container-imageというオプションでイメージを変更することもできます。

参考

Add-onコンポーネント#

pod-master#

pod-masterはHigh-Availability構成時にkube-scheduler, kube-controller-managerがどのMasterで動くかを調整するコンテナです。etcdを使ってロックをするシンプルな仕組みで、200行程度のgoのプログラムです(参考podmaster.go)。ロックを取得したMasterサーバーがローカルのマニフェストファイルを反映させるというやり方で、どのMasterでkube-schedulerkube-controller-managerを動かすか調整しています。kubernetesレポジトリのdocs/admin/high-availabilitypodmaster.yamlの設定例が参考になります。

kube-scheduler, kube-controller-manager自体にもリーダー選出の機能(--leader-electオプション)が実装されているようなので、今後は不要になるコンポーネントかもしれません。(参考 pkg/client/leaderelection)

参考

kube-dns#

kube-dnsはクラスタ内DNSのPodの名前です。Serviceリソースが作られた時、kube-dnsに登録され、クラスタ内部から名前解決できるようになります。デフォルトではcluster.localというドメインが使われます。Serviceは{Service名}.{ネームスペース}.svc.cluster.localという形式のFQDNでAレコード、SRVレコードに登録されます。

kube-dnsのPodは以下の4コンテナで構成されています。

  • skydns DNSサーバー
  • etcd skydnsのデータを保存する専用etcd
  • kube2sky SkyDNSにKubernetesの情報を反映させるブリッジ
  • healthz 定期的にnslookupしてヘルスチェックを行う

参考

SkyDNS 🔗#

クラスタ内のDNSとして使われているDNSサーバーです(kube-dnsの一部)。データの永続化にはetcdが用いられます。

参考

kube2sky#

SkyDNSにKubernetesの情報を反映させるブリッジです。KubernetesのAPIでService, Endpoints, Podをwatchし、SkyDNSのetcdに書き込むことでDNSの情報を反映させます。

参考

heapster#

heapsterはクラスタ全体の使用状況を集約するためのコンポーネントです。ストレージはプラガブルな仕組みになっており、InfluxDB, Google Cloud Monitoring, Kafkaなど複数のストレージをサポートします。

参考#


最後の更新: