0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

KubernetesのNodeとは何か?Podとの関係からEKSの構成まで理解する

0
Posted at

はじめに

前回は、Kubernetesでコンテナを動かす最小単位であるPodについて学びました。

Podの中では、RailsやSidekiqなどのコンテナが動きます。

では、そのPod自体は、どこで動いているのでしょうか。

そこで登場するのが Node(ノード) です。

この記事では、次の内容を整理します。

  • Nodeとは何か
  • PodとNodeの関係
  • Nodeの中で動くコンポーネント
  • Podを配置するNodeはどのように決まるのか
  • Nodeで障害が起きた場合に何が起こるのか
  • EKS・EC2・Node Groupの関係
  • NodeとVPC・Subnet・AZの関係

結論

Nodeとは、Podを実際に動かすコンピューターです。

Nodeは、物理マシンの場合もあれば、仮想マシンの場合もあります。

AWSのEKSでEC2を利用する構成では、基本的に1台のEC2インスタンスが1つのNodeとしてKubernetesクラスターへ参加します。

Kubernetesクラスター
├── Node 1(EC2)
│   ├── Rails Pod
│   │   └── Railsコンテナ
│   └── Sidekiq Pod
│       └── Sidekiqコンテナ
│
└── Node 2(EC2)
    └── Rails Pod
        └── Railsコンテナ

最も簡単に表すと、次の関係です。

Nodeの中でPodが動く
Podの中でコンテナが動く

Nodeとは

Kubernetesは、複数のコンピューターをまとめて1つのクラスターとして管理します。

そのクラスターに参加し、Podを実行するコンピューターがNodeです。

Kubernetesクラスター
├── Node 1
├── Node 2
└── Node 3

各Nodeには、CPU・メモリ・ディスク・ネットワークなどのリソースがあります。

Kubernetesは、それらの空き状況やPodの条件を確認しながら、PodをいずれかのNodeへ配置します。

Nodeは、環境によって異なる実体を持ちます。

環境 Nodeの例
自分のPCで学習する環境 Docker Desktopなどが用意する仮想マシン
オンプレミス 物理サーバー・仮想マシン
AWS EKS EC2インスタンスなど
Google Kubernetes Engine Compute EngineのVMなど

つまり、NodeはKubernetes独自の仮想的な箱ではありません。

実際のコンピューターをKubernetesへ登録し、Podを動かせる状態にしたものがNodeです。

Cluster・Node・Pod・Containerの関係

ここまで登場した要素を入れ子で表すと、次のようになります。

Kubernetesクラスター
└── Node
    └── Pod
        └── Container

それぞれの役割は次のとおりです。

要素 役割
Cluster 複数のNodeやKubernetesの管理機能をまとめた全体
Node Podを実際に動かすコンピューター
Pod コンテナをまとめて動かすKubernetesの最小単位
Container RailsやSidekiqなどのアプリケーションを実行する

1つのNodeでは、複数のPodを動かせます。

一方、1つのPodが複数のNodeにまたがって動くことはありません。

Node 1
├── Pod A
├── Pod B
└── Pod C

Node 2
├── Pod D
└── Pod E

Pod内に複数のコンテナがある場合も、そのコンテナはすべて同じNode上で動きます。

Control PlaneとNodeの関係

Kubernetesクラスターは、大きく次の2つに分けられます。

Kubernetesクラスター
├── Control Plane
│   └── クラスター全体を管理する
│
└── Node
    └── Podを実際に動かす

Control Planeは、クラスターの状態を管理する側です。

たとえば、次のような判断や管理を行います。

  • Podを何個動かす必要があるか
  • 新しいPodをどのNodeへ配置するか
  • NodeやPodが正常な状態か
  • 現在の状態を、指定された状態へ近づけるには何が必要か

Nodeは、Control Planeから伝えられた内容に基づいてPodを動かす側です。

簡単に分けると、次のように考えられます。

Control Plane:決める・管理する
Node         :実際に動かす

AWS EKSでは、Control PlaneをAWSが管理します。

一方、EC2を使用するNodeは、ユーザー側のAWSアカウント内で動きます。

Nodeの中では何が動いているのか

NodeがPodを動かすためには、主に次のコンポーネントが必要です。

Node
├── kubelet
├── container runtime
├── kube-proxy
└── Pod
    └── Container

kubelet

kubeletは、それぞれのNode上で動くKubernetesのエージェントです。

Control Planeから、そのNodeで動かすPodの情報を受け取り、Pod内のコンテナが指定どおり動くように管理します。

Control Plane
「このPodを、このNodeで動かしてください」
        ↓
kubelet
「コンテナランタイムへ起動を依頼します」
        ↓
container runtime
「コンテナを起動します」

kubeletは、主に次のような役割を持ちます。

  • Podの定義を受け取る
  • コンテナランタイムへコンテナの起動を依頼する
  • コンテナが正常に動いているか確認する
  • NodeやPodの状態をControl Planeへ報告する
  • Liveness ProbeやReadiness Probeなどのヘルスチェックを実行する

ただし、kubelet自身がコンテナを直接実行するわけではありません。

実際のコンテナ実行は、コンテナランタイムが担当します。

container runtime

container runtimeは、コンテナイメージを取得し、コンテナを実際に起動・停止するソフトウェアです。

代表例として、containerdやCRI-Oがあります。

kubelet
    ↓ 起動を依頼
container runtime
    ├── コンテナイメージを取得
    ├── コンテナを作成
    └── コンテナを起動

Dockerについて学んだ際に登場した「コンテナを実際に動かす部分」に近い役割です。

Kubernetesは、CRIという共通の仕組みを通じてコンテナランタイムと連携します。

kube-proxy

kube-proxyは、Node上のネットワークルールを管理し、Service宛ての通信を適切なPodへ届けるために使われるコンポーネントです。

Service宛ての通信
        ↓
Node上のネットワークルール
        ↓
対象のPod

Serviceが持つ安定した接続先と、実際に動いているPodをつなぐ役割を支えます。

ただし、利用するネットワーク構成によっては、kube-proxyを使わず別の仕組みで同等の処理を行う場合もあります。

Podを配置するNodeは誰が決めるのか

新しいPodをどのNodeへ配置するか決めるのは、Control Planeで動く kube-scheduler です。

たとえば、DeploymentによってRails Podを1個増やす場合、次のように進みます。

1. Deployment
   「Rails Podを3個にしたい」
        ↓
2. 新しいPodが必要になる
        ↓
3. kube-scheduler
   「どのNodeなら動かせるか確認します」
        ↓
4. Node 2を選択
        ↓
5. Node 2のkubelet
   「Pod内のコンテナを起動します」

kube-schedulerは、Nodeを選ぶ際に次のような条件を確認します。

  • Nodeに十分なCPU・メモリがあるか
  • Podが要求する条件をNodeが満たしているか
  • Nodeに設定されたtaintをPodが許容できるか
  • node affinityなどの配置条件に一致するか
  • 複数のNodeへPodを分散できるか

つまり、kubeletが配置先を決めるわけではありません。

kube-scheduler:配置するNodeを決める
kubelet       :決められたNode上でPodを動かす

CPU・メモリとPodの配置

Nodeで動かせるPodの数は、単純に「最大10個」などと固定されているわけではありません。

NodeのCPU・メモリやネットワーク上の上限、Podが要求するリソースなどによって変わります。

Podでは、コンテナが必要とするCPUとメモリをrequestsで指定できます。

resources:
  requests:
    cpu: "250m"
    memory: "256Mi"
  limits:
    cpu: "500m"
    memory: "512Mi"

それぞれの意味は次のとおりです。

項目 意味
requests Podを配置する際に必要として扱うCPU・メモリ
limits コンテナが使用できるCPU・メモリの上限

kube-schedulerは、主にrequestsを見て、Podを配置できるNodeを探します。

Nodeの配置可能なメモリ:1Gi
新しいPodのrequests:256Mi
        ↓
配置できる可能性がある

反対に、条件を満たすNodeがなければ、PodはPendingのままになります。

新しいPodに必要なメモリ:2Gi
空き条件を満たすNode:0台
        ↓
PodはPending

この場合は、Nodeを増やす、Nodeを大きくする、Podのリソース指定を見直すなどの対応が必要です。

Nodeの状態

NodeがPodを動かせる状態かどうかは、次のコマンドで確認できます。

kubectl get nodes

出力例は次のようになります。

NAME       STATUS   ROLES    AGE   VERSION
node-1     Ready    <none>   10d   v1.xx.x
node-2     Ready    <none>   10d   v1.xx.x

STATUSがReadyであれば、基本的にPodを受け入れられる状態です。

詳細を確認する場合は、次のコマンドを使用します。

kubectl describe node node-1

Nodeでは、次のようなConditionが管理されます。

Condition 意味
Ready Nodeが正常で、Podを受け入れられるか
MemoryPressure メモリ不足の圧力があるか
DiskPressure ディスク不足の圧力があるか
PIDPressure プロセスIDが不足する圧力があるか
NetworkUnavailable Nodeのネットワークが利用できない状態か

たとえば、Nodeからの状態報告が途絶えると、NotReadyなどの状態になります。

Nodeで障害が起きたらどうなるのか

Nodeが停止すると、そのNode上で動いていたPodも動けなくなります。

障害発生前
Node 1
├── Rails Pod A
└── Sidekiq Pod B

Node 1で障害
        ↓
Pod A・Pod Bも利用できなくなる

Deploymentなどのコントローラーに管理されているPodであれば、Control Planeは必要なPod数が不足していることを検知し、利用可能な別のNodeへ代わりのPodを作成します。

Node 1で障害
        ↓
Rails Pod Aが利用できない
        ↓
指定されたPod数を満たしていない
        ↓
Node 2に新しいRails Pod Cを作成

ここで重要なのは、停止したPodそのものがNode 2へ移動するわけではないことです。

別のNodeで、代わりとなる新しいPodが作成されます。

また、1台のNodeしかなければ、そのNodeが停止した際に代わりのPodを動かす場所がありません。

複数Nodeや複数AZを使う構成は、障害時にもアプリケーションを継続しやすくするために重要です。

Nodeを安全にメンテナンスする

Nodeを更新・停止する際、いきなり終了すると、そのNode上のPodも突然停止してしまいます。

そこで、KubernetesにはNodeからPodを安全に退避させるための操作があります。

cordon

cordonは、そのNodeへ新しいPodが配置されない状態にします。

kubectl cordon node-1

すでに動いているPodは、そのまま動き続けます。

drain

drainは、新しいPodの配置を止めたうえで、対象Node上のPodを退避させます。

kubectl drain node-1 --ignore-daemonsets

コントローラーに管理されているPodは、必要に応じて別のNodeに作り直されます。

uncordon

メンテナンス後、再びPodを配置できるようにします。

kubectl uncordon node-1

流れをまとめると、次のようになります。

cordon
新しいPodの配置を止める
        ↓
drain
既存のPodを退避させる
        ↓
Nodeをメンテナンスする
        ↓
uncordon
再びPodを配置できるようにする

EKSではNodeは何に当たるのか

AWSのEKSで一般的なEC2ベースの構成を使う場合、NodeはEC2インスタンスに当たります。

Amazon EKSクラスター
├── Control Plane
│   └── AWSが管理
│
└── Node
    └── EC2インスタンス
        └── Pod
            └── Container

ただし、EKSとEC2が同じものという意味ではありません。

要素 役割
EKS Kubernetesクラスターを提供・管理するAWSサービス
EC2 Podを動かすための計算リソースとして使える仮想マシン
Node EC2などをKubernetesへ参加させたときの呼び方

つまり、EC2インスタンスがEKSクラスターへ参加し、Podを実行できる状態になると、KubernetesからはNodeとして見えます。

Node Groupとは

EKSでは、複数のNodeをまとめて管理するために Node Group を使用できます。

EKSクラスター
└── Node Group
    ├── Node 1(EC2)
    ├── Node 2(EC2)
    └── Node 3(EC2)

NodeとNode Groupの違いは次のとおりです。

用語 意味
Node Podを動かす1台のコンピューター
Node Group 同じような設定を持つ複数のNodeをまとめたグループ

EKSのManaged Node Groupを使うと、EC2 Nodeの作成・更新・終了などのライフサイクル管理をEKSに任せやすくなります。

Managed Node Groupでは、EC2 Auto Scaling Groupを利用してNode数を管理します。

Managed Node Group
└── EC2 Auto Scaling Group
    ├── Node 1(EC2)
    ├── Node 2(EC2)
    └── Node 3(EC2)

たとえば、次のような設定を持てます。

  • 最小Node数
  • 希望するNode数
  • 最大Node数
  • EC2のインスタンスタイプ
  • 使用するAMI
  • On-DemandまたはSpotのキャパシティタイプ

NodeとVPC・Subnet・AZの関係

EKSでEC2 Nodeを使う場合、そのEC2はVPC内のSubnetへ配置されます。

AWSアカウント
└── VPC
    ├── Private Subnet(AZ-a)
    │   └── Node 1(EC2)
    │       ├── Rails Pod
    │       └── Sidekiq Pod
    │
    └── Private Subnet(AZ-c)
        └── Node 2(EC2)
            └── Rails Pod

ここでの関係は次のとおりです。

要素 意味
VPC AWSアカウント内に作るプライベートネットワーク
Subnet VPCをIPアドレス範囲とAZごとに分割した区画
AZ 互いに物理的・設備的に分離されたデータセンター群
EC2 Node Subnet内に配置され、Podを動かす仮想マシン

VPCは複数のAZにまたがれますが、1つのSubnetは1つのAZに属します。

また、EC2 Nodeも、配置されたSubnetが属する1つのAZで動きます。

複数AZにNodeを分けておけば、1つのAZで障害が起きても、別のAZにあるNodeでPodを動かせる可能性があります。

Podを増やすこととNodeを増やすことの違い

PodのスケーリングとNodeのスケーリングは、別の操作です。

Podを増やす
= アプリケーションの実行単位を増やす

Nodeを増やす
= Podを載せるコンピューターを増やす

たとえば、アクセス増加に合わせてRails Podを3個から10個へ増やそうとしても、Nodeに空きがなければ新しいPodを配置できません。

Rails Podを10個にしたい
        ↓
Nodeの空きが足りない
        ↓
一部のPodがPendingになる
        ↓
Nodeを追加する
        ↓
新しいNodeへPodを配置できる

一般的には、次のような仕組みを組み合わせます。

仕組み 増減させる対象
Horizontal Pod Autoscaler Pod数
Cluster Autoscalerなど Node数

Podを増やす仕組みと、そのPodを載せるNodeを増やす仕組みは、役割が異なります。

よくある勘違い

NodeはPodのこと?

違います。

NodeはPodを動かすコンピューターで、PodはNode上でコンテナを動かす単位です。

Node
└── Pod
    └── Container

NodeはKubernetesが作る仮想マシン?

必ずしもそうではありません。

Nodeの実体は物理マシンや仮想マシンです。EKSでEC2を使う場合は、EC2をクラスターへ参加させることでNodeになります。

1つのPodは複数のNodeで動く?

動きません。

1つのPodは必ず1つのNodeへ配置されます。Pod内のコンテナもすべて同じNode上で動きます。

Nodeが停止するとPodが別のNodeへ移動する?

停止したPodそのものが移動するわけではありません。

Deploymentなどで管理されていれば、別のNodeに代わりの新しいPodが作成されます。

Nodeを増やせばPodも自動的に増える?

増えません。

Nodeを増やすとPodを配置できる容量は増えますが、DeploymentのreplicasやHorizontal Pod AutoscalerなどでPod数を増やさない限り、必要なPod数は変わりません。

NodeとNode Groupは同じもの?

違います。

Nodeは1台のコンピューターで、Node Groupは複数のNodeをまとめて管理する単位です。

まとめ

Nodeについて、重要な点をまとめます。

  • Nodeは、Podを実際に動かすコンピューター
  • Nodeの実体は、物理マシンまたは仮想マシン
  • EKSでEC2を使う場合、基本的に1台のEC2が1つのNodeになる
  • 1つのNodeでは複数のPodを動かせる
  • 1つのPodが複数のNodeにまたがることはない
  • kube-schedulerがPodを配置するNodeを決める
  • kubeletがNode上でPodの状態を管理する
  • container runtimeがコンテナを実際に起動・停止する
  • NodeのCPUやメモリが不足すると、Podを配置できずPendingになる場合がある
  • Node障害時は、別のNodeで代わりのPodが新しく作られる
  • Node Groupは複数のNodeをまとめて管理する単位
  • EKSのEC2 Nodeは、VPC内のSubnetへ配置される
  • 可用性を高めるには、複数のNodeやAZへPodを分散することが重要

最も簡単に覚えるなら、次の関係です。

Control Planeが管理する
        ↓
NodeがPodを動かす
        ↓
PodがContainerを動かす

EKSまで含めると、次のようになります。

EKSクラスター
└── Node Group
    └── Node(EC2)
        └── Pod
            └── Container

Podを理解したあとにNodeを学ぶと、Kubernetesが「コンテナをどのコンピューターへ配置し、どのように動かしているのか」が見えやすくなります。

参考資料

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?