ITの教科書検索
入門読了 約11分

Kubernetesとは ― Podとコントロールプレーン

Kubernetesは、多数のコンテナの配置・再起動・数の調整を自動で行う仕組みです。Pod・Deployment・Serviceの関係と、止まったPodが戻る流れを図を動かして追えます。

目次
  1. Kubernetesとは
  2. あるべき状態に近づける仕組み
  3. コントロールプレーンとノード
  4. Podとは
  5. Deploymentとは
  6. Podが止まったときの動き
  7. Serviceとは
  8. Kubernetesが受け持たないこと
  9. マネージドのKubernetes
  10. 練習問題

Kubernetesとは、多数のコンテナを自動で動かし続ける仕組み

コンテナの数が増えると、どのサーバに置き、止まったらどう起動し直し、いくつ動かすかを人の手で管理しきれなくなります。Kubernetesは、この3つを自動で行う仕組みです。利用者があるべき状態を宣言しておくと、Kubernetesがいまの状態をそこへ近づけ続けます。

公式ドキュメントは、Kubernetesを、コンテナ化したアプリを管理するためのオープンソースのプラットフォームと説明しています。2014年にGoogleがオープンソースとして公開し、2016年からはCNCFのプロジェクトになっています。CNCFは、クラウド向けのオープンソースを支える団体です。Kubernetesは2018年に、CNCFの成熟度の段階でGraduatedに上がりました。

KとSの間に8文字あることから、K8sと略して書かれることもあります。

宣言型で動く:あるべき状態といまの状態を比べて近づける

Kubernetesには、「このPodを3つ動かす」のように、最終的にどうなっていてほしいかを書いて渡します。Podは、コンテナをまとめて動かす単位です。どの順に何を起動するかの手順は書きません。この書き方は、IaCでいう宣言型と同じ考え方です。

公式ドキュメントは、この仕組みを部屋のエアコンの温度設定にたとえています。設定した温度があるべき状態で、いまの室温がいまの状態です。エアコンは、室温を設定に近づけるように動き続けます。

Kubernetesで同じ役をするのが、コントローラーです。コントローラーは、クラスターの状態を見続け、あるべき状態との差があれば直します。状態を見て直す動きを止まらずに繰り返すことを、公式ドキュメントは制御ループと呼んでいます。差を埋めて状態を合わせる動きなので、調整ループとも呼ばれます。

Kubernetesは、コンテナのオーケストレーションの代表例として挙げられます。ただし公式ドキュメントは、決めた手順をAからCへ順に実行するのとは違うと説明しています。独立した複数の制御の仕組みが、いまの状態をあるべき状態へ近づけ続けるからです。

クラスターの構成は、コントロールプレーンとワーカーノード

Kubernetesで管理するサーバの集まりを、クラスターと呼びます。クラスターは、全体を管理するコントロールプレーンと、コンテナを実際に動かすワーカーノードに分かれます。ワーカーノードは単にノードとも呼ばれ、物理サーバでも仮想マシンでもかまいません。

コントロールプレーンkube-controller-managerコントローラーを動かすkube-scheduler置くノードを選ぶkube-apiserverAPIの窓口etcd保存先Podを増減割り当てる記録Podの割り当てワーカーノード1kubeletkube-proxyランタイムPodコンテナPodコンテナワーカーノード2kubeletkube-proxyランタイムPodコンテナService振り分ける利用者アクセスコントロールプレーンkube-controller-managerコントローラーを動かすPodを増減kube-apiserverAPIの窓口etcd記録割り当てるkube-scheduler置くノードを選ぶPodの割り当てワーカーノード1kubeletkube-proxyランタイムPodPodワーカーノード2kubeletkube-proxyランタイムPodService振り分けるアクセス利用者
コントロールプレーンの部品は、APIサーバを窓口にしてクラスターの状態を書き換えます。ワーカーノードは割り当てられたPodを動かし、Serviceは2台に散ったPodへアクセスを振り分けます。

コントロールプレーンの構成要素どうしは、APIサーバを窓口にしてつながります。コントローラーやスケジューラーは、APIサーバを通して状態を読み、変更を書き込みます。APIサーバは、受け付けた内容をetcdに保存します。

ワーカーノードには、kubelet、kube-proxy、コンテナランタイムが入ります。kubeletは、自分のノードに割り当てられたPodのコンテナが動いているように保ちます。コンテナランタイムは、containerdやCRI-Oのように、コンテナを実際に起動するソフトウェアです。

Kubernetesの主な構成要素(Kubernetes公式ドキュメント「Cluster Architecture」による)
構成要素置く場所役目
kube-apiserverコントロールプレーンKubernetesのAPIを受け付ける窓口。ほかの構成要素はここを通して状態を読み書きする
etcdコントロールプレーンクラスターのデータをすべて保存するキーバリュー型の保存先
kube-schedulerコントロールプレーンノードが決まっていないPodを見つけ、置くノードを選ぶ
kube-controller-managerコントロールプレーンDeploymentなどのコントローラーを動かし、いまの状態をあるべき状態に近づける
kubeletワーカーノード割り当てられたPodのコンテナが動いているように保つ
kube-proxyワーカーノードServiceあての通信をPodへ届ける規則をノードに作る
コンテナランタイムワーカーノードコンテナを実際に起動して動かす。containerdやCRI-Oなど

本番の環境では、ふつうコントロールプレーンを複数のサーバに分けて動かし、ノードも複数台にします。どれか1台が止まっても、クラスター全体が止まらないようにするためです。クラウドの事業者と連携する構成要素として、cloud-controller-managerを加えることもあります。

Podとは、コンテナをまとめて動かす最小の単位

Podとは、1つ以上のコンテナをまとめた、Kubernetesで作って管理できる最小の単位です。Kubernetesはコンテナを直接ではなく、Podとして置き場所を決め、起動し、止めます。

同じPodの中のコンテナは、同じノードで動き、ネットワークと保存領域を分け合います。Podには1つずつIPアドレスが割り当てられ、中のコンテナどうしはlocalhostで通信できます。公式ドキュメントによると、1つのPodに1つのコンテナを入れる形がいちばん多い使い方です。

Podは、使い捨てる前提で作られています。ノードの故障や資源の不足で消えることがあり、消えたPodがそのまま戻ることはありません。そのためPodはふつう直接作らず、次の節で説明するDeploymentなどに作らせます。

Deploymentとは、Podの数を保ち、順に入れ替えて更新する仕組み

Deploymentとは、Podのひな形と、同じ作りのPodをいくつ動かすかを書いておくものです。Deploymentは、指定した数のPodを保つReplicaSetを作り、ReplicaSetが実際のPodを作ります。

次の例は、公式ドキュメントにあるDeploymentの定義です。nginxのイメージを使うPodを3つ動かすように宣言しています。

Podを3つ保つDeploymentの定義(YAML)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

replicasが、保ちたいPodの数です。templateの中が、Podのひな形にあたります。selectorは、このDeploymentが受け持つPodを、app: nginxというラベルで見分ける指定です。

ひな形のイメージを新しい版に書き換えると、Deploymentは新しいReplicaSetを作ります。そして新しいPodを少しずつ増やし、古いPodを少しずつ減らします。この入れ替え方をローリングアップデートと呼び、更新の途中も動いているPodで処理を続けられます。

初期設定では、入れ替えの途中に使えるPodがあるべき数の75%を下回らないようにします。Podの合計は、あるべき数の125%までに抑えます。更新後のPodがうまく動かないときは、前の版に戻すこともできます。ローリングアップデートとほかの切り替え方の違いは、ブルーグリーンデプロイとカナリアリリースの記事で比べています。

Podが止まったとき・数を変えたときに、Kubernetesの中で起きること

Podが1つ消えると、あるべき数といまの数に差が生まれます。その差をコントローラー・スケジューラー・kubeletが順に埋めていきます。次の図で場面を選び、段を進めると、どの構成要素が何をするかを1段ずつ確かめられます。

Deploymentでreplicasを3にしてあり、Podが3つ動いている状態から始めます。
あるべき状態 3いまの状態 2
ノード1動いているPod動いているPod
ノード2消えたPod
  1. 起きたこと
    ノード2で動いていたPodが1つ消えました。あるべき数は3のままで、いま動いているのは2つです。
  2. ReplicaSetコントローラー(kube-controller-managerの中)
    あるべき数との差に気づき、足りない1つ分のPodをAPIサーバを通して作ります。このPodは、まだ置き先のノードが決まっていません。
  3. kube-scheduler
    置き先の決まっていないPodを見つけ、空きのあるノードを選びます。この例ではノード2を選び、その結果をAPIサーバに伝えます。
  4. ノード2のkubelet
    自分のノードに割り当てられたPodに気づき、コンテナランタイムにコンテナを起動させます。いま動いているPodが3つに戻りました。
  5. Service
    新しいPodが応答できる状態になると、Serviceの振り分け先に加わります。利用者は、Podが入れ替わったことを意識せずに使い続けられます。
1 / 5

どの場面でも、コントローラーはPodを直接起動しません。APIサーバに書き込み、スケジューラーとkubeletがその内容を見て動きます。公式ドキュメントは、この自動で元に戻す働きを自己修復と呼んでいます。

Podの中のコンテナが落ちただけのときは、Podは作り直されません。そのノードのkubeletが、設定に従ってコンテナを再起動します。ただし公式ドキュメントは、アプリそのものの不具合は再起動では直らないと注意しています。

replicasは手で変えるほか、CPUの使用率などに応じて自動で変えることもできます。この仕組みをHorizontalPodAutoscalerと呼び、Podの数を増やして負荷に応えます。台数を増やして処理を分ける考え方は、スケールアップとスケールアウトの記事で説明しています。

Serviceとは、入れ替わるPodの前に置く変わらない接続先

Podは作り直されるとIPアドレスが変わり、置かれるノードも変わることがあります。Serviceとは、条件に合うPodの集まりの前に置き、変わらない接続先を与える仕組みです。利用者や別のアプリは、Serviceに向けて通信すれば、いま動いているPodのどれかに届きます。

app: nginxのPodに振り分けるServiceの定義(YAML)
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

この例は、公式ドキュメントのServiceの例と同じ書き方で、selectorを前の節のDeploymentに合わせたものです。Serviceは、app: nginxのラベルを持つPodを見つけ、80番ポートへの通信をPodの80番ポートへ送ります。Podが入れ替わると、振り分け先の一覧も自動で書き換わります。

typeを書かないと、Serviceはクラスターの中だけで使えるIPアドレスを持ちます。外から使えるようにするには、ノードのポートで受けるNodePortや、外部のロードバランサを使うLoadBalancerを選びます。振り分けの考え方は、ロードバランサの記事が詳しいです。

図ではServiceを1つの箱で描きましたが、Serviceは専用の機械ではありません。各ノードのkube-proxyなどが、Serviceあての通信をPodへ届ける規則を作っています。

Kubernetesが受け持たないこと

Kubernetesの仕事はコンテナを動かし続けることで、アプリを作る仕組みまでは持ちません。公式ドキュメントは、Kubernetesが行わないこととして次のものを挙げています。

  • ソースコードのビルドとデプロイ。この流れはCI/CDの仕組みで別に用意します
  • ログの収集・監視・通知の仕組みの決定。連携のための仕組みだけを用意しています
  • データベースやメッセージの仲介などの、アプリが使うサービスそのもの

これらは、Kubernetesの上で動かすか、外のサービスを組み合わせて用意します。どの道具を選ぶかは、利用者に任されています。

マネージドのKubernetesは、コントロールプレーンの運用を事業者に任せる形

コントロールプレーンを自分で組み、止まらないように運用するのは手間がかかります。そこで、クラウドの事業者がコントロールプレーンを運用するサービスがあります。Amazon EKS・Google Kubernetes Engine・Azure Kubernetes Serviceが、その例です。

これらのサービスでも、Pod・Deployment・Serviceの考え方は変わりません。ワーカーノードの管理まで事業者に任せる方式を用意しているサービスもあります。AWSでEKSがどの層の選択肢になるかは、ECSの記事でAmazon ECSと比べています。

参考にした資料

練習問題(全5問)

Q1Kubernetesで、作って管理できる最小の単位はどれ?
Q2Deploymentでreplicasを3にしたあと、Podが1つ消えた。このあと起きることとして正しいものはどれ?
Q3ノードが決まっていないPodを見つけ、置くノードを選ぶ構成要素はどれ?
Q4Serviceを置く理由として、最も適切なものはどれ?
Q5Kubernetesの公式ドキュメントが、Kubernetesに含まれないものとして挙げているものはどれ?

選んでから「採点する」を押すと、解説つきで答え合わせができます。

関連記事

クラウドの記事を続けて読む

クラウド 全36本中14本目