Kubernetesって何?をなんとなく理解するために、Kubernetesの動作に焦点を当てて、概要をまとめてみました。
Kubernetesを一言でいうと、
業界標準のOSSのコンテナオーケストレータです。
コンテナ
Kubernetesの理解の為にはコンテナについて知っておく必要があります。
コンテナで何ができるか知ってから、コンテナオーケストレータ(Kubernetes)で何ができるか学びましょう!
コンテナを一言でいうと、
専用のOS上で動いているような分離状態を作り出した、OS上のプロセスです。
このコンテナ上に、開発環境やアプリケーション実行環境、サービスなどを詰め込んで、どこでも実行することができます。
コンテナを動作させる一連の流れ
では実際にコンテナを動作させる一連の流れを見てみましょう!
まずはコンテナ作ってー!とコンテナ係にお願いします。
このコンテナを扱う係の事をコンテナランタイムと言います。
実際には高位ランタイムと中位ランタイム(CRI)と低位ランタイム(OCI)が動作を分担していますが、ここではシンプルに「ランタイム」でまとめて解説します。
よく聞くDockerというのもコンテナランタイムの名前です。
Dockerとはコンテナの事ではなく、コンテナを扱うためのプログラムのことを指すんですね。
コンテナ作成をお願いされたランタイム君は、コンテナの素を探しに展示場に行きます。
このコンテナの素のことをコンテナイメージ、展示場のことをレジストリ(DockerHubなど)と言います。厳密にはレジストリとリポジトリがありますが、ここではシンプルに概念だけつかんでいただけたらと思います。
そしてコンテナイメージを持って帰ってきてコンテナを実行します。
もちろんレジストリに無いコンテナイメージも、設計書があれば作成することができます。
この設計書のことをdockerfileと言います。
実際のdockerfileの例です。
FROM centos:7
RUN yum install -y java
RUN touch /tmp/test.txt # 変更箇所
ADD files/apache-tomcat-9.0.6.tar.gz /opt/
CMD ["/opt/apache-tomcat-9.0.6/bin/catalina.sh", "run"]
FROMでレジストリにあるコンテナイメージを指定して、そのコンテナイメージに対して、RUN以下の記述の作業を実施して、新しいコンテナイメージを作成します。
こんな動作のおかげでコンテナは、共通のレジストリにアクセスできる環境にdockerfileを持ち込むことで、すぐに別の環境でも実行することができます!
他にも様々な工夫の上でいろいろな長所がありますが、
まとめると以下のようになります。
コンテナの特長
- 可搬性が高い
- 容量が軽量で、起動が早い
- 仮想マシンに比べてリソースのオーバーヘッドが少ない
コンテナ用語まとめ
ここまでで出てきたコンテナ用語をまとめます。
- コンテナ:専用のOS上で動いているような分離状態を作り出した、OS上のプロセス
- コンテナランタイム:コンテナを扱うためのプログラム
- コンテナイメージ:コンテナの素になるもの
- レジストリ,リポジトリ:コンテナの素を公開・保存している場所
- dockerfile:コンテナの素の設計書
Kubernetesでのコンテナの扱い
KubernetesではコンテナをPodという単位で扱います。
コンテナをPodという入れ物に入れて、抽象化して扱います。
Pod≠コンテナという事を理解するのが大切です。
図のように、1Pod上で複数のコンテナを動作させることができます。
同一Pod上のコンテナはKubernetes内で同じIPアドレスを持つので、localhostにて同一Pod上の他のコンテナと相互に通信することができます。
Kubernetesアーキテクチャ
KubernetesはMasterノードと、Workerノードという2種類の役割で構成させています。
管理会社と工場のようなイメージです。
色々とコンポーネントが動いていて、それぞれ役割はありますが、コンテナに焦点を当てて非常に簡単に言うと、
コンテナなどの作成や管理の指示をMasterノードで統括していて、実際にコンテナを扱うのがWorkerノード
という事になります。
このMasterノードとWorkerノードの一つのまとまりをKubernetesクラスタと呼びます。
Kubernetesノードの呼び方
余談ですがMasterノード、Workerノードにはいろいろな呼び方があるので混乱しないようにしましょう!
特に海外のドキュメントと日本のドキュメントなどで統一されていないように感じます。
Masterノード:master, controller, controllplane
Workerノード:worker, ノード
日本の書籍ではWorkerノードをただ単にノードと呼ぶことが多いですが、Masterノードという呼び方もあり混乱していますので、この記事ではWorkerノード、Masterノードと表記しています。
Kubernetesでコンテナを動作させる一連の流れ
それではKubernetesでコンテナを動作させる動きの中で、Masterノード・Workerノードの各コンポーネントの役割を見ていきましょう!
まずはコンテナ作成の指示をするときに、作成するコンテナを乗せるPodの作成も一緒に指示する必要があります。KubernetesではPod無しでコンテナを動作させることはありません。
という事で、ユーザからPod・コンテナの作成依頼を受けて、Masterノードに依頼を届ける係、kubectl君の登場です。
kubectl君はコマンドか、yaml形式の指示書(マニフェスト)で依頼を受けて、Masterノードのkube-apiserverにAPIで「こんな条件でPod作ってー」と指示を送ります。
kube-apiserverとは
Kubernetesの操作の連絡を受け持っているコンポーネントです。
KubernetesAPIを提供して、内部のコンポーネント同士のやり取りもkube-apiserverを通して行われています。
kubectl君はMasterノードでもWorkerノードでもそれ以外のマシンにも乗ることができて、kube-apiserverの情報さえあればどこからでも指示を送ることができます。
指示を受けたkube-apiserverは掲示板のようなものに「誰かこんな条件でPodつくってー」と指示を書き込みます。
この掲示板のようなものがetcdです。
etcdとは
分散型キーバリューストアで、Kubernetesクラスタに登録されている全ての情報を保存しています。とても大切な情報の倉庫なので、掲示板というより図書館に近いかもしれません。。
ここで仕事割当て屋のkube-schedulerの登場です。
kube-schedulerとは
kube-schedulerさんはPod起動依頼の書き込みを検知すると、担当の決まっていない依頼「誰か」の担当を様々な状況を見て判断して、「Workerノード1号」のように担当を書き込みます。
またこの時のetcdへの書き込みもkube-apiserverを介して行われていますが、ややこしくなるのでイラストでは省略させていただきます。
さて、この時点では担当Workerノードが決まっていて、起動していないPodがある状態です。
この状態を検知して、Podの起動を行うのがWorkerノードにいるkubeletです。
kubeletとは
各Workerノード上にいて、コンテナランタイムと連携してPodの起動や停止などの管理を行います。ここではWorkerノード1号にいたkubeletが担当の割り当てを検知してPodを起動しました。
これでKubernetesクラスタ上で、Podの起動ができました!
Kubernetesの通信について
Kubernetesではクラスタ内のPod同士で通信を行うことができます。
これは、Workerノードをまたいでいても可能です。
それを実現しているのがcni-pluginです。
cniには様々な実現方法がありますが、ここでは詳細は省略します。
cni-pluginによってPod間通信ができるというイメージを覚えていただければ十分です。
外からのPodへの通信はどうするの?
そうです!そこで登場するのがServiceとkuber-proxyです!
KubernetesのServiceとkube-proxyによってPodに通信が運ばれます。
ここでポイントなのは、kube-proxyはKubernetesのWorkerノードのコンポーネントであるのに対して、ServiceはKubernetesのリソースであるという点です。
混乱しないでください。
大丈夫です。
つまり、kube-proxyはkube-apiserverやkubeletなどの仲間(コンポーネント)で、
ServiceはPodと同じように、kubectlから指示を出して作成したり削除したりできるもの(リソース)ということです。
このように作成されたService通りに、kube-proxyが通信を行っています。
kube-proxyも様々な設定があり奥が深いので、ここでは説明を省略します。
KubernetesのController
- 同じPodを常に3つ起動しておきたい。
- 全てのノードに1つずつ同じPodを配置したい。
先に説明した通りの方法や、コンテナランタイムのみだとかなり手間がかかってしまいます。
これを簡単に実現できるのがコンテナオーケストレータの売りです!
そのためにはControllerというKubernetesのリソースを使います。
まずは1つめ、[1.同じPodを常に3つ起動しておきたい。]を実現するためには、DeploymentControllerを使います。
Controllerを作成するには、Pod作成と同じようにkubectlからkube-apiserverに依頼を行います。
実際にControllerを起動するのはkube-controller-managerです。
DeploymentControllerは指定された個数のPodが常に実行されるように制御するControllerです。
実際にDeploymentControllerをはじめとするControllerはPodをetcdに登録するまでを担当して、実行Workerノードの割り当ては全てkube-schedulerが行っています。
2つ目[2.全てのノードに1つずつ同じPodを配置したい。]を実現するためには、DaemonSetControllerを使います。
DaemonsetControllerは全てのWorkerノードにPodを割り当てるControllerです。
Kubernetes用語まとめ
構成ノード
- Masterノード:Kubernetesクラスタ全体を管理する司令塔のような存在。
- Workerノード:実際にPodが実行されるサーバ。
コンポーネント
Masterノード
- kubectl :コマンドやYAML形式でKubernetesAPIを発行する。
- etcd:Kubernetesのすべての情報を保存する分散型KVS(キーバリューストア)。
- kube-apiserver:KubernetesAPIを提供して、内部の操作の受付を行う。
- kube-controller-manager:登録されたControllerを実行する。
- kube-scheduler:登録されたPodを適切なWorkerノードに割り当てる。
Workerノード
- kubelet:割り当てられたPodを起動したり管理を行う。
- kube-proxy:Serviceリソースに基づいた通信を実現する。
- cni-plugin:Pod間の通信のネットワークを提供する。
リソース
- Pod:抽象化してコンテナを乗せる入れ物。
- Service:外部や内部の通信を定義する。
- Controller:Podなどのリソースを管理するリソース。
DeploymentController:replicasetと連携して、Podの起動数を管理する。
DaemonsetController:すべてのノードにPodを配置するController。
おわりに
最後までお付き合いいただきありがとうございました。
インフラエンジニアの為のという事で、動作などを少し細かく説明したので長くなってしまいました。
他にもいろいろな動作ができるので、気になった方はぜひ学習を始めてみてください!
以下では書籍での学習方法を紹介しています。
また、インフラエンジニアならハンズオントレーニングはKubernetes The Hard Wayがおすすめですので、良かったらチャレンジしてみてください。
本家はGoogleCloudPlatformに構築するトレーニングですが、本Webサイトではローカル環境でチャレンジした時の概要を紹介しています。
ハンズオン後に環境を残したい方など、良かったら合わせてご覧ください。