kubernetesアーキテクチャまとめ


はじめに

記事で挙げているkubernetesアーキテクチャ(Master構成)は、k8sを利用する上で必ず必要という訳ではないですが、筆者はCKA(Certificate Kubernetes Administorator)資格をきっかけにk8sの仕組みを知り、k8sを使うことに対する怖さが全くなくなりました。
CKAに無事合格できたので、kubernetesアーキテクチャの概要をまとめてみました。

kubernetesアーキテクチャ概観

k8sはMasterWorker Nodeの2つに分けることができます。Masterは、4つのコアコンポーネントで構成され、k8sの各種機能を実現しています。Worker Nodeは、主にpodをデプロイするために使用されるノードです。

API Server

API Serverは、多くの場合staticPodとしてkube-systemネームスペースに存在します。API Serverの役割は各コンポーネントとのやり取りで、HUBとして機能をします。クライアントとのkubectlコマンドも、API Serverが受け付けます。

API Server~クライアント

クライアントとAPI Serveの通信はTSLによって暗号化されています。この暗号化情報や、クライアントが接続するクラスター(API Server)の情報は、KubeConfigで設定します。

Scheduler

Schedulerは、多くの場合staticPodとしてkube-systemネームスペースに存在します。Schedulerの役割は、podを実行するノードを決定することです(デプロイはkubeletが行います)。kubernetesでは、pod実行ノードに制約をかけることのできる機能が多く存在します。

podが実行されるノードに対する制約

機能 説明
taint taintは、tolerationを持たないpodのデプロイを防ぎます
affinity affinityをpodに設定することで、特定のnodeにデプロイさせることができます
drain drainにより、特定のノードへのデプロイを防ぎます
required resource podデプロイ時にノードに要求するCPUやメモリを指定できます

etcd

etcdは、Key-Valueベースのデータベースで、クラスター情報を管理します。etcdの実体は、多くの場合kube-systemネームスペースのDeploymentです。このetcdのスナップショットを取っておくことで、クラスターのリストアが可能です。このように、etcdはクラスターにとって最も大切なコンポーネントであり、単一障害点にならないように冗長化されることも多いです。

ETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot save snapshotdb // etcdのsnapshotを取得
ETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot restore snapshotdb // etcdのrestoreが可能

※ etcdはAPI Serverと異なるTLSサーバ証明書を持つことが一般的です。
  上記コマンド実行の際は、オプションでetcdのTLS証明書の指定が必要な場合が多いです。

controller manager

controller managerは、多くの場合staticPodとしてkube-systemネームスペースに存在し、各種kubernetesリソースのコントローラーの役割をします。例えば、controller managerに含まれるdeployment-controllerは、
「kubernetesリソースのdeploymentで定義されれているreplica数」と「実際にRunning状態の対象Pod数」を比較して、スケールイン/スケールアウトの司令をだします。controller managerが正常に動作していないと、「kubectl scaleコマンド実行したのに、pod数が変わらない」スケールされないなどの事象が起きます。

kubelet

kubeletは、各ノードのデーモンサービスとして動作します。
kubeletの主な役割は、
 ・API Serverの司令によるpodデプロイ
 ・ノード指定フォルダ配下のpodデプロイ(staticPodとしてデプロイされます)
 ・メトリクスをAPI Serverに送信
です。

kube proxy

kubeletは、daemonSetとしてkube-systemネームスペースに存在します(daemonSetは、任意のpodを各ノードに1つずつデプロイすることを可能にします)。kube proxyはトラフィック管理を行います。

Serviceの実体からみる、kube proxyの役割

kubernetesは、Dockerのオーケストレーションサービスです。つまり、kubernetesが行うのはDockerの"管理"で、全てのコンポーネントはDocker上で動作します。Kubernetesリソースは、Docker上でどのように存在しているのでしょうか??
例えば、Podであれば、Pod内の各コンテナはDockerコンテナとしてデプロイされます。Serviceはどうでしょうか?ServiceのようなDockerリソースは存在しません。Serviceの実体は、iptableのようなネットワーク設定です。kube proxyがkubernetesリソースであるServiceを検知して、Serviceをネットワーク設定に変換します。

kubectlデプロイまでの流れ

kubectlでPod作成コマンド実行~Podデプロイまでの一連の流れです。
以下、コマンド例です。

kubectl run --generator=run-pod/v1 hoge --image=nginx
  1. kubectl → API Server
    kubectlコマンドは、API Serverが受け付けます。
    クライアントへのレスポンスは、2 のetcd更新後に返却します。

  2. API Server → etcd
    API Serverは、etcdに作成するpod情報を記録します。
    この時点で、podはPending状態になります。

  3. Scheduler → API Server
    Schedulerは、etcdからデプロイされていないpodを検知し、
    CPU・メモリ要求に応じてデプロイするノードを決定し、API Serverに教えます。

  4. API Server → kubelet
    API Serverは、Schedulerが決定したノードのkubeletにpod作成要求を出し、
    kubeletがPodデプロイをします。
    デプロイ完了をすると、podはRunning状態になります。

【参考】
https://github.com/kubernetes/kubedash